将instanceof与java枚举一起使用

f5emj3cl  于 2021-07-05  发布在  Java
关注(0)|答案(4)|浏览(449)

我有一种情况,我收到了一封信 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] found   : java.lang.Enum<capture#117 of ? extends java.lang.Enum<?>>
    [javac] required: myEnum
    [javac]             if( externalEnum instanceof MyEnum )

我得到了这个函数的一个版本,只需返回 MyEnum.valueOf(externalEnum.name()) -它起作用了,这才是最重要的。然而,我对编译器错误感到困惑。
我试图理解这个案例中泛型的具体化过程。一个例子 Enum<? extends Enum<?>> 或者只是 Enum<?> 可以是一个 MyEnum (考虑到后者永远不能是前者的子类型以外的任何东西。)
所以 instanceof 测试应该是有效的,但是在通用的 Enum (可能还有枚举不能扩展的事实),这会导致编译器对该特定语句产生呕吐。
解决方法对我来说很容易,但我喜欢理解的问题,以及在这方面的任何见解将不胜感激。
路易斯。

yqyhoc1h

yqyhoc1h1#

如果两者都是一样的,为什么还要麻烦呢?

public static MyEnum enumToEnum(final Enum<? extends Enum<?>> externalEnum)
{
    try
    {
        return MyEnum.valueOf(externalEnum.name());
    }
    catch (Exception ex)
    {
        return MyEnum.UNKNOWN;
    }
}
bkkx9g8r

bkkx9g8r2#

我想你是说 externalEnum 而不是 enumType 在你的第一份回报声明中。
修复了这个问题,它在eclipse和ant中编译。

iyzzxitl

iyzzxitl3#

有一种情况,我从外部系统接收到一个枚举,为此我需要返回一个我们自己的枚举。
如果两个类都由不同的类加载器加载和/或具有不同的次要/主要版本,instanceof将返回false。也要考虑到这一点。

8nuwlpux

8nuwlpux4#

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

Enum<? extends Enum<?>>

表示“扩展某个未知类型的枚举的类型的枚举”。
你想要的可能更像这样:

Enum<T extends Enum<T>>

意思是“扩展自身枚举的类型的枚举”。这是一个奇怪的递归定义(以某种方式循环回到 Comparable<T> ),但这只是 Enum 定义了。
当然,静态方法需要接受类型参数 <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());
    }
}

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

相关问题