在界面中使用泛型

时间:2013-03-26 16:08:49

标签: java generics

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

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

public class MyEvent<T> extends EventObject {

    // code
}

2 个答案:

答案 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的值,因为该类型信息存储在反射数据中。

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