更新: 感谢所有提供帮助的人-这个答案的答案在于我在更复杂的代码中没有注意到的内容以及对Java5协变量返回类型不了解的内容。
原始帖子:
今天早上我一直在玩一些东西。虽然我知道我 可以用 不同的方式解决整个问题,但我发现自己一直迷恋于弄清楚为什么它没有按我预期的那样工作。在花了一些时间阅读这些内容之后,我发现我离理解还很近,因此我将其作为一个问题来看看我是否只是愚蠢,或者是否真的有我不理解的事情。
我已经创建了一个自定义事件层次结构,如下所示:
public abstract class AbstractEvent<S, T extends Enum<T>> { private S src; private T id; public AbstractEvent(S src, T id) { this.src = src; this.id = id; } public S getSource() { return src; } public T getId() { return id; } }
像这样的具体实现:
public class MyEvent extends AbstractEvent<String, MyEvent.Type> { public enum Type { SELECTED, SELECTION_CLEARED }; public MyEvent(String src, Type t) { super(src, t); } }
然后,我创建一个像这样的事件:
fireEvent(new MyEvent("MyClass.myMethod", MyEvent.Type.SELECTED));
我的fireEvent定义为:
protected void fireEvent(MyEvent event) { for(EventListener l : getListeners()) { switch(event.getId()) { case SELECTED: l.selected(event); break; case SELECTION_CLEARED: l.unselect(event); break; } } }
因此,我认为这将非常简单,但是事实证明,对event.getId()的调用导致编译器告诉我无法打开Enums,只能打开可转换的int值或枚举常量。
可以向MyEvent添加以下方法:
public Type getId() { return super.getId(); }
一旦执行此操作,一切便会完全按照我的预期进行。我不仅对找到一种解决方法感兴趣(因为我显然有一个解决方法),而且我对人们可能对为什么这样做不起作用的任何见解都感兴趣,因为我期望它很快就会实现。
Yishai是正确的,魔术短语是“ 协变量返回类型 ”,它是Java 5.0的新功能- 您不能打开Enum,但是可以打开扩展Enum的Type类。MyEvent继承的AbstractEvent中的方法可以擦除类型。通过覆盖它,可以将getId()Java可以在运行时处理的方式重定向到Type类。
getId()