Java 枚举与类装入器

Java 枚举与类装入器,java,enums,Java,Enums,有时,您甚至可能不知道插入代码的环境有多个类加载器。在这种情况下,操作“==”仍能对枚举值起作用吗?“==”不起作用,但您还是希望使用.equals() 您可能对apache commons lang类感兴趣:多个类加载器可能不是问题,只要枚举仅通过其中一个类加载器可用。如果不是这样,您将失去枚举的所有好处 顺便说一下,使用equals()也没有帮助。以下是Java 1.6中Enum.equals(Object)的实现: public final boolean equals(Object ot

有时,您甚至可能不知道插入代码的环境有多个类加载器。在这种情况下,操作“==”仍能对枚举值起作用吗?

“==”
不起作用,但您还是希望使用
.equals()


您可能对apache commons lang类感兴趣:

多个类加载器可能不是问题,只要枚举仅通过其中一个类加载器可用。如果不是这样,您将失去枚举的所有好处

顺便说一下,使用
equals()
也没有帮助。以下是Java 1.6中
Enum.equals(Object)
的实现:

public final boolean equals(Object other) { 
    return this==other;
}

如果您的枚举类只加载一次,它仍然可以工作。

  • 您的枚举仅在加载的插件中使用
  • 枚举已由单个插件类加载器的父类加载器加载

如果您的枚举类由不同的类加载器加载,则它将不起作用

  • 在不同插件之间传递枚举值,但应用程序类加载器尚未加载枚举。(如果枚举值从不在插件之间交叉,它仍然可以工作)
为什么会这样


Java使用对象实例来表示不同的枚举值,每个实例都作为静态字段存储在enum类中。如果枚举加载两次,则每个枚举值由两个不同的对象实例表示。
==运算符
仅比较引用,不知道表示枚举值的多个实例,因此它将无法匹配不同类加载器加载的值

顺便说一句,Enum
equals()
的实现只调用
this==other
(Sun/oraclejdk6)。是的,正如我在自己的回答中所写的,这可能适用于本版本。但是,按照语言语义,
=
将永远无效,而
.equals()
可能(!)起作用。另请参阅apache commons枚举实现。我知道==和equals()之间的重要区别。但enum故意违反了这一区别,这一点不太可能改变。虽然我同意equals在这里是一个更好的选择,就像josefx的帖子中所说的语义上的我一样;当一个枚举被多个类加载器加载时,它仍然可以工作,你只需要小心它们彼此隔离。当然,但这很痛苦。它打破了人们对枚举的任何假设。它打破了枚举单例模式。类加载器打破了所有单例模式。“==运算符只比较引用”听起来有点像信条。枚举已经是一个非常特别的东西了。还有一个特性可以将“==”定义为“this.ordinal()==that.ordinal()”。这能解决问题吗?@Dima只要两个加载的枚举定义相同,它就可以工作。序数值仅包含源代码中枚举常量的索引(位置),如果代码更改(新值、不同顺序),它仍将中断。如果速度不是问题,你可以比较他们的名字。