我遇到了有关 Java 泛型的问题。
我正在尝试创建一个监听器(称为 SomeEventListener
)来监听 SomeEvent
。发生。这些事件有一个特定类型的结果;我希望通过方法 getResult()
检索结果,其返回类型为T
。当该事件被触发时,eventOccurred(SomeEvent<T>)
方法被调用。
SomeEvent 类:
public class SomeEvent<T> {
private T result;
public SomeEvent(T result) {
this.result = result;
}
public T getResult() {
return this.result;
}
}
SomeEventListener 类:
public interface SomeEventListener<T> {
void eventOccurred(SomeEvent<T> event);
}
AnotherClass 类
public class AnotherClass {
ArrayList<SomeEventListener<?>> listeners = new ArrayList<SomeEventListener<?>>();
<T> void fireSomethingOccursEvent(SomeEvent<T> event) {
for (SomeEventListener<?> listener : this.listeners) {
listener.eventOccurred(event); // MARKED LINE
}
}
}
但是,Eclipse 在标记行上给出了错误:
The method eventOccurred(SomeEvent<capture#2-of ?>) in the type SomeEventListener<capture#2-of ?> is not applicable for the arguments (SomeEvent<T>)
我怀疑为什么会发生这种情况 - 它可能与泛型和类型删除有关 - 但我无法解决它。
我的问题:
- 为什么上述代码无效?
- 如何修复代码?
注意:关于泛型和/或类型删除的帖子很多;但是,我找不到这个问题的答案。如果您认为其他答案合适,请链接到它。
最佳答案
您有一个SomeEventListener<?>
,使用方法 void eventOccurred(SomeEvent<?> event)
(将 ?
替换为 T
)。
您还有一个 SomeEvent<T>
对于一些完全不相关的T
.
您无法将其转换为 SomeEvent<?>
- 事实上,您无法将任何内容转换为 SomeEvent<?>
除了 null
。 ?
意思是“我不知道这个类型参数是什么。”
举个例子,如果您的代码被允许,该代码将编译,但传递错误的类型:
AnotherClass ac = new AnotherClass();
ac.listeners.add(new SomeEventListener<Integer>() {
void eventOccurred(SomeEvent<Integer> event) {
System.out.println(event.intValue());
}
});
SomeEvent<String> event = new SomeEvent<String>("Hello");
ac.fireSomethingOccursEvent(event);
现在fireSomethingOccursEvent
将采取 SomeEvent<String>
并将其传递给 SomeEventListener<Integer>
。这显然是不允许的 - 所以,这是不允许的。
关于java - 方法不适用于有关 Java 中泛型或类型删除的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24552389/