Chr*_*ran 18 java generics enums switch-statement
更新:感谢所有帮助过的人 - 这个问题的答案在于我在更复杂的代码中没有注意到的内容以及我对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;
}
}
Run Code Online (Sandbox Code Playgroud)
具体实现如下:
public class MyEvent
extends AbstractEvent<String, MyEvent.Type>
{
public enum Type { SELECTED, SELECTION_CLEARED };
public MyEvent(String src, Type t)
{
super(src, t);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建一个这样的事件:
fireEvent(new MyEvent("MyClass.myMethod", MyEvent.Type.SELECTED));
Run Code Online (Sandbox Code Playgroud)
我的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我认为这将非常简单,但事实证明,对event.getId()的调用导致编译器告诉我无法打开枚举,只能转换int值或枚举常量.
可以将以下方法添加到MyEvent:
public Type getId()
{
return super.getId();
}
Run Code Online (Sandbox Code Playgroud)
一旦我这样做,一切都按照我的预期完成.我不只是对找到一个解决方法感兴趣(因为我显然有一个),我对人们可能有的任何见解感兴趣,为什么这不起作用,因为我预期它会立即起作用.
这与泛型无关.java中枚举的switch语句只能使用该特定枚举的值,因此禁止实际指定枚举名.这应该工作:
switch(event.getId()) {
case SELECTED:
l.selected(event);
break;
case SELECTION_CLEARED:
l.unselect(event);
break;
}
Run Code Online (Sandbox Code Playgroud)
更新:好的,这是一个实际的代码(我必须改变一点才能让它编译而没有依赖)我已经复制/粘贴,编译和运行 - 没有错误:
AbstractEvent.java
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;
}
}
Run Code Online (Sandbox Code Playgroud)
MyEvent.java
public class MyEvent extends AbstractEvent<String, MyEvent.Type> {
public enum Type { SELECTED, SELECTION_CLEARED };
public MyEvent(String src, Type t) {
super(src, t);
}
}
Run Code Online (Sandbox Code Playgroud)
Test.java
public class Test {
public static void main(String[] args) {
fireEvent(new MyEvent("MyClass.myMethod", MyEvent.Type.SELECTED));
}
private static void fireEvent(MyEvent event) {
switch(event.getId()) {
case SELECTED:
System.out.println("SELECTED");
break;
case SELECTION_CLEARED:
System.out.println("UNSELECTED");
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这在Java 1.5下编译和运行就好了.我在这里错过了什么?