在Java中使用泛型和反射实现接口方法

Using Generics and Reflections in Java for interface method implementation

我正在尝试使用 Guice 解决一个练习。我已经完成了几乎所有其他的事情,但是这个方法的实现让我神魂颠倒。此方法的目的是充当记录器的注册商,还有另一种方法将充当向正确记录器(@named loggers)发送消息的方法。我不太担心调度员,因为我知道该怎么做。但是 registrar 方法必须使用泛型和反射。我被严重困在这里,在 "java.lang.Class".

中使用反射时,我的 Java 经验几乎不存在

代码如下:

class MyManagerImpl implements MyMgr {

    /* MyListener below is an interface */
    public synchronized void regService(Class<? extends MyListener> loggerObj) {
    ...
    ...
    ...
    }

    public synchronized void dispatch(String msg, String logger) {
          / * dispatches the messages to the correct logger which
            * I know how to do 
            *
            */    
    }


}

我理解上面启用通配符的类型表达式表示 "Class contains anytype that implements of, or extends, MyListener interface"。但我对使用 Class 匿名很陌生。是否有可能看到一个例子,其中这个 loggerObj 实际上是 modified/used 来调用一个成员函数。

我猜你的代码没有多大意义,将通过的是 Class 实例,因此要用于反射,你 不能调用 任何方法。你或许可以反思一下。

更好的尝试是:

public synchronized void doService(<? extends MyListener> listenerObj) {
    //...
    //...
    //...
}

但这将毫无意义,因为您可以将其替换为:

public synchronized void doService(MyListener listenerObj) {
    //...
    //...
    //...
}

泛型仅用于 Collection<T> 类型,例如:

public synchronized void doService(Collection<? extends MyListener> listenerObj) {
    //...
    //...
    //...
}

这样你就可以用ArrayList<SubMyListener>ArrayList<SubSubMyListener>等调用它。这是因为下面的继承关系不成立:

ArrayList<SubSubMyListener> extends ArrayList<SubMyListener>

为什么有用?:

假设您希望使用 MyListener 个对象进行某种集合,现在您可以提供一个带有签名的方法:

Foo method (Collection<? extends MyListener> bars) {

}

但是如果要调用带有Collection<SubMyListener>的方法,它不遵循继承,所以编译器不会允许它。通过使用通配符,您可以做到这一点。

您可以使用此约束,调用在 MyListener 上定义的方法。例如:

void callAll (Collection<? extends MyListener> bars) {
    for(MyListener bar : bars) {
        bar.call();
    }
}

现在在 for 循环中,Java 导出一个 Iterator<? extends MyListener>。换句话说,Java 知道,Iterator 只会发出继承自 MyListener 的对象,这可以用来让 Java 可以执行类型检查,因此比希望对象确实是 MyListener 个对象更安全。