我有一个问题,关于界面中正确的方法签名是什么,以及为什么。我的事件是用类型参数化的,但是接口是否还有<T>
在方法签名中使用它?如果是这样,为什么不呢?
public interface MyListener {
void beforeAction(final MyEvent event);
}
和
public class MyEvent<T> extends EventObject {
// code
}
答案 0 :(得分:4)
如果使用某种类型参数化MyEvent
,则需要将MyListener
指定为
public interface MyListener<T> {
void beforeAction(final MyEvent<T> event);
}
或者如果MyEvents
有不同类型的MyListener
并非特定于封闭public interface MyListener {
<T> void beforeAction(final MyEvent<T> event);
}
,则:
public interface MyListener {
void beforeAction(final MyEvent<?> event);
}
或者,正如托马斯所说,你可以完全忽略T的类型:
{{1}}
您必须执行上述操作之一,否则您将收到有关使用原始类型的编译器警告。
答案 1 :(得分:2)
如果T
的类型在您的监听器中无关紧要,您至少应该将方法定义为void beforeAction(final MyEvent<?> event);
,以便消除警告并保持泛型启用。如果没有任何类型,编译器将禁用该方法的所有类型检查。
如果你想为不同类型的事件设置不同的监听器,你应该将T
添加到你的界面,就像安德鲁已经指出的那样。
通过这种方式,您可以创建多个侦听器实现,而无需手动转换(以及错误),例如:像这样的东西:
public class StringListener implements MyListener<String> {
void beforeAction(final MyEvent<String> event) {
...
}
}
public class NumberListener implements MyListener<Number> {
void beforeAction(final MyEvent<Number> event) {
...
}
}
如果您有这样的实现,您还可以在运行时查询T
的值,因为该类型信息存储在反射数据中。
请注意,匿名类或局部变量不适用 - 在这种情况下会发生类型擦除。