我正在尝试使用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实际被修改/用于调用成员函数的示例。
答案 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
个对象。