在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
个对象更安全。
我正在尝试使用 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
个对象更安全。