3

我有一个关于接口中正确的方法签名是什么以及为什么的问题。我的事件是用类型参数化的,但是接口是否也应该<T>在方法签名中使用它?如果是,为什么,为什么不呢?

public interface MyListener {
    void beforeAction(final MyEvent event);
}

public class MyEvent<T> extends EventObject {

    // code
}
4

2 回答 2

5

如果MyEvent使用类型参数化,则MyListener需要指定为

public interface MyListener<T> {
    void beforeAction(final MyEvent<T> event);
}

或者如果有不同类型的MyEvents不是特定于封闭的MyListener,那么:

public interface MyListener {
    <T> void beforeAction(final MyEvent<T> event);
}

或者,正如 Thomas 所说,您可以完全忽略 T 的类型:

public interface MyListener {
    void beforeAction(final MyEvent<?> event);
}

您必须执行上述操作之一,否则您将收到有关使用原始类型的编译器警告。

于 2013-03-26T16:11:08.490 回答
2

如果T您的侦听器中的类型无关紧要,您至少应该将方法定义为void beforeAction(final MyEvent<?> event);以消除警告并保持泛型启用。如果没有任何类型,编译器将禁用该方法的所有类型检查。

如果您想为不同类型的事件设置不同的侦听器,您也应该将其添加T到您的界面中,就像 Andrew 已经指出的那样。

通过这种方式,您可以创建多个侦听器实现,而无需手动强制转换(以及错误),例如:

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在运行时查询 的值,因为该类型信息存储在反射数据中。

请注意,这不适用于匿名类或局部变量——在这些情况下会发生类型擦除。

于 2013-03-26T16:17:22.017 回答