使用Java泛型与枚举 [英] Using Java Generics with Enums

查看:292
本文介绍了使用Java泛型与枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:感谢所有帮助的人 - 对这个答案的回答在于我没有注意到我更复杂的代码,以及我不了解Java5协方差返回类型。

Update: Thanks for everyone who helped out - the answer to this one lay in what I wasn't noticing in my more complex code and what I didn't know about the Java5 covariant return types.

原始帖子

我早上在玩耍。虽然我知道我可以可以不同地处理这个整个问题,但我发现自己很痴迷于弄清楚为什么它不能像我所期待的那样工作。在花了一些时间阅读之后,我发现我没有更接近理解,所以我提出了一个问题,看看我是否只是愚蠢的,或者如果真的有一些我不明白的东西在这里

I've been playing around with something this morning. While I know that I could tackle this whole problem differently, I'm finding myself obsessed with figuring out why it isn't working the way that I was expecting. After spending some time reading around on this, I find I'm no closer to understanding, so I offer it up as a question to see if I'm just being stupid or if there is really something I don't understand going on here.

我已经创建了一个这样的自定义事件层次:

I have created a custom Event hierarchy like so:

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);
    }
}

然后我创建一个这样的事件: p>

And then I create an event like so:

fireEvent(new MyEvent("MyClass.myMethod", MyEvent.Type.SELECTED));

我的fireEvent定义为:

Where my fireEvent is defined as:

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()的调用导致编译器告诉我,我无法打开枚举,只能转换int值或枚举常量。

So I thought that this would be pretty straightforward but it turns out that the call to event.getId() results in the compiler telling me that I cannot switch on Enums, only convertible int values or enum constants.

可以将以下方法添加到MyEvent:

It is possible to add the following method to MyEvent:

public Type getId()
{
    return super.getId();
}

一旦我这样做,一切都按照我的预期工作。我不是只想找一个解决方法(因为我显然有一个),我有兴趣的人们可能有什么见解为什么这不工作,因为我期望它的蝙蝠。 p>

Once I do this, everything works exactly as I expected it to. I'm not just interested in finding a workaround for this (because I obviously have one), I'm interested in any insight people might have as to WHY this doesn't work as I expected it to right off the bat.

推荐答案

Yishai是对的,魔术短语是协变式返回类型 - 您无法启用Enum,但您可以打开Type类扩展枚举。由MyEvent继承的AbstractEvent中的方法受到类型擦除。通过覆盖它,您将以Java的方式在运行时处理,将 getId()的结果重定向到Type类。

Yishai is right, and the magic phrase is "covariant return types" which is new as of Java 5.0 -- you can't switch on Enum, but you can switch on your Type class which extends Enum. The methods in AbstractEvent that are inherited by MyEvent are subject to type erasure. By overriding it, you're redirecting the result of getId() towards your Type class in a way that Java can handle at run-time.

这篇关于使用Java泛型与枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆