将instanceof与Java枚举一起使用

发布于 2024-08-10 00:54:17 字数 1086 浏览 8 评论 0原文

我遇到了一种情况,我从外部系统接收到一个 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> 或简单的 Enum 可以是 MyEnum (假设后者永远不能是子类型以外的任何东西) )

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

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

  • 路易斯.

I have a situation where I'm receiving an enum from an external system, and for which I need to return an enum of our own. The two enums have the exact same literal values in them:

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

However, the compiler squeals the following:

    [javac] found   : java.lang.Enum<capture#117 of ? extends java.lang.Enum<?>>
    [javac] required: myEnum
    [javac]             if( externalEnum instanceof MyEnum )

I got a version of that function that works by simply returning MyEnum.valueOf(externalEnum.name()) - it works and that's all that matters. However, I'm baffled about the compiler error.

I'm trying to understand the reification process of generics in this case. An instance of Enum<? extends Enum<?>> or simply Enum<?> can be a MyEnum (given that the later can never be anything other than a subtype of the former.)

So the instanceof test should work, but there seems to be something in the generic definition of Enum (and perhaps the fact that Enums cannot be extended) that causes the compiler to puke with that particular statement.

The workaround for me is easy, but I like to understand the problems well, and any insight on this will be appreciated.

  • Luis.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

天涯离梦残月幽梦 2024-08-17 00:54:17

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

Enum<? extends Enum<?>>

表示“扩展枚举的类型的枚举,该枚举扩展了某些未知类型”。

你想要的可能更像是这样的:

Enum<T extends Enum<T>>

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

当然,您的静态方法需要采用类型参数 才能正常工作。试试这个:

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

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

My (possibly flawed) analysis of your problem is that the two wildcards in your type definition are separate from each other:

Enum<? extends Enum<?>>

means "An Enum of a type that extends Enum that extends some unknown type".

What you want is probably more like this:

Enum<T extends Enum<T>>

which means "An Enum of a type that extends Enum of itself". That is a curious recursive definition (which somehow loops back to Comparable<T>), but it's just how Enums are defined.

Of course your static method would need to take a type parameter <T> for this to work. Try this:

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

Edit: fixing the compiler error caused by a wrong identifier makes the code in the question compile for me. So my analysis is definitely flawed ;-)

幽蝶幻影 2024-08-17 00:54:17

如果两者相同,为什么还要麻烦呢?

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

Why even bother if both are the same?

public static MyEnum enumToEnum(final Enum<? extends Enum<?>> externalEnum)
{
    try
    {
        return MyEnum.valueOf(externalEnum.name());
    }
    catch (Exception ex)
    {
        return MyEnum.UNKNOWN;
    }
}
我ぃ本無心為│何有愛 2024-08-17 00:54:17

我认为您在第一个返回语句中指的是 externalEnum 而不是 enumType

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

I think you mean externalEnum rather than enumType in your first return statement.

That fixed, it compiles in Eclipse and with ant.

鸵鸟症 2024-08-17 00:54:17

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

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

I have a situation where I'm receiving an enum from an external system, and for which I need to return an enum of our own.

The instanceof will return false if both classes are loaded by different classloader and/or do have a different minor/major version. Take this into account as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文