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

时间:2015-01-07 01:19:51

标签: java generics reflection guice

我正在尝试使用Guice解决练习。我已经完成了其他所有事情,但是这种方法实现让我的灵魂感到困惑。此方法的目的是充当记录器的注册器,还有另一种方法,它将作为发送消息发送到正确的记录器(@named记录器)。我并不担心调度员太多,因为我知道如何做到这一点。但注册商方法必须使用泛型和反射。我非常困在这里,当使用“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包含实现或扩展MyListener接口的任何类型”。但是我对使用Class进行匿名是一个新手。是否可以看到这个loggerObj实际被修改/用于调用成员函数的示例。

1 个答案:

答案 0 :(得分:1)

你的代码没有多大意义我猜,一个人会传递的是 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个对象。