一尘不染

将Java泛型与枚举一起使用

java

更新: 感谢所有提供帮助的人-这个答案的答案在于我在更复杂的代码中没有注意到的内容以及对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();
}

一旦执行此操作,一切便会完全按照我的预期进行。我不仅对找到一种解决方法感兴趣(因为我显然有一个解决方法),而且我对人们可能对为什么这样做不起作用的任何见解都感兴趣,因为我期望它很快就会实现。


阅读 329

收藏
2020-12-03

共1个答案

一尘不染

Yishai是正确的,魔术短语是“
协变量返回类型
”,它是Java 5.0的新功能-
您不能打开Enum,但是可以打开扩展Enum的Type类。MyEvent继承的AbstractEvent中的方法可以擦除类型。通过覆盖它,可以将getId()Java可以在运行时处理的方式重定向到Type类。

2020-12-03