1

我有一种情况,我enum从外部系统接收一个,为此我需要返回一个enum我们自己的。这两个枚举具有完全相同的文字值:

// externalEnum is guaranteed not to be null 
public static MyEnum enumToEnum(final Enum<? extends Enum<?>> externalEnum)
{
    if( externalEnum instanceof MyEnum )
    {
        return (MyEnum)enumType;
    }
    else
    {
        return MyEnum.valueOf(externalEnum.name());
    }
}

但是,编译器会发出以下声音:

    [javac] 发现:java.lang.Enum<capture#117 of ? 扩展 java.lang.Enum<?>>
    [javac] 必需:myEnum
    [javac] if( externalEnum instanceof MyEnum )

我得到了该函数的一个版本,只需返回即可MyEnum.valueOf(externalEnum.name())工作 - 它可以工作,这才是最重要的。但是,我对编译器错误感到困惑。

在这种情况下,我试图了解泛型的具体化过程。的一个实例Enum<? extends Enum<?>>或简单地Enum<?>可以是一个MyEnum(假设后者永远不能是前者的子类型以外的任何东西。)

所以instanceof测试应该可以工作,但是在通用定义中似乎有一些东西Enum(也许是 Enums 不能扩展的事实)导致编译器对该特定语句产生呕吐。

对我来说,解决方法很简单,但我喜欢很好地理解问题,对此的任何见解将不胜感激。

  • 路易斯。
4

4 回答 4

3

我对您的问题的(可能有缺陷的)分析是您的类型定义中的两个通配符彼此分开:

Enum<? extends Enum<?>>

意思是“一个类型的枚举,它扩展了一些未知类型的枚举”。

你想要的可能更像这样:

Enum<T extends Enum<T>>

这意味着“扩展自身枚举的类型的枚举”。这是一个奇怪的递归定义(它以某种方式循环回Comparable<T>),但这就是Enums 的定义方式。

当然,你的静态方法需要一个类型参数<T>才能工作。尝试这个:

public static <T extends Enum<T>> MyEnum enumToEnum(final T externalEnum) {
    if (externalEnum instanceof MyEnum) {
        return (MyEnum) externalEnum;
    } else {
        return MyEnum.valueOf(externalEnum.name());
    }
}

编辑:修复由错误标识符引起的编译器错误使问题中的代码为我编译。所以我的分析肯定有缺陷;-)

于 2009-11-03T14:38:19.440 回答
2

如果两者都相同,为什么还要打扰?

public static MyEnum enumToEnum(final Enum<? extends Enum<?>> externalEnum)
{
    try
    {
        return MyEnum.valueOf(externalEnum.name());
    }
    catch (Exception ex)
    {
        return MyEnum.UNKNOWN;
    }
}
于 2009-11-03T21:18:28.237 回答
1

我认为您的意思是externalEnum而不是enumType在您的第一个退货声明中。

修复后,它可以在 Eclipse 和 ant 中编译。

于 2009-11-03T15:26:19.687 回答
1

我有一种情况,我从外部系统接收枚举,为此我需要返回我们自己的枚举。

如果两个类都由不同的类加载器加载和/或确实具有不同的次要/主要版本,则 instanceof 将返回 false。也要考虑到这一点。

于 2009-11-03T15:29:33.213 回答