我知道Java枚举被编译成具有私有构造函数和一组公共静态成员的类。在比较给定枚举的两个成员时,我总是使用.equals(),例如
1 2 3 4 5 6 7 8
| public useEnums(SomeEnum a)
{
if(a.equals(SomeEnum.SOME_ENUM_VALUE))
{
...
}
...
} |
但是,我刚刚遇到一些代码使用equals操作符==而不是.equals():
1 2 3 4 5 6 7 8
| public useEnums2(SomeEnum a)
{
if(a == SomeEnum.SOME_ENUM_VALUE)
{
...
}
...
} |
我应该用哪个接线员?
- 我刚刚偶然发现了一个非常相似的问题:stackoverflow.com/questions/533922/…
- 我很惊讶,在所有的答案中(特别是PolyGene润滑剂中的一个,它详细解释了为什么==有效),没有提到==的另一个巨大好处:它明确了枚举是如何工作的(作为一组固定的单例对象)。当它等于时,人们会认为同一个枚举"alternative"可能有多个实例浮动。
- 保持简单。"=="可读性更强,因为枚举在默认情况下是单例的。裁判
两者在技术上都是正确的。如果您查看.equals()的源代码,它只需遵从==。
不过,我使用==,因为这将是无效安全的。
- 就我个人而言,我不喜欢把‘零安全’作为使用==的理由。
- 我赞同这个答案,因为运行时性能也有了微小的改进。
- @为什么不呢?你喜欢担心你的论点的顺序吗(这只适用于比较左边的常量,如帕斯卡的答案)?您是否喜欢在使用.equals()之前检查值是否不为空?我知道我不知道。
- @卡尔·斯莫特里茨(Carl Somricz),equals很可能是由JIT内联的,所以性能不是问题。
- 请记住,在读取代码时,阅读器可能会发现"=="不正确,直到他/她关闭并查看所涉及类型的源,然后看到它是枚举。从这个意义上说,读".equals()"就不那么分心了。
- @Kevin-如果你没有使用一个允许你在查看源代码时直接看到类型的IDE,那你就是在欺骗自己-这不是正确的IDE的问题。
- @根据惯例,以东人的名字都是用大写字母写的…因此,如果有人遇到一个全大写的名字,他们是否有理由相信它是final原始的(即int或long或enum,而使用==是正确的?
- 不,事实上,这不是一个合理的假设,因为人们使用所有大写的名称来表示许多、许多类型的常量。
- 枚举是最终的,所以==工作正常。就我个人而言,我只是把它作为常量,用==进行比较。
- 如果您关心空的安全性,并且这对字符串常量也有效,请将要比较的值放在左侧:"blah".equals(variablepossiblenull)和someEnum.constant.equals(enumreferencepossiblenull)都有效,但只有.equals对枚举常量和字符串都有效。如果您真的对它有点偏执,请查看ApacheCommonsLang中的objectutils.equals(ob1,ob2),它将处理所有情况!
- 有时代码会被重构,很可能枚举会被类替换,此时==不再保证是正确的,而equals继续无缝工作。因此,平等显然是一个更好的选择。如果您希望使用空安全(因为您使用的代码库不是为了最小化空值的使用而编写的),那么可以使用apache objectuils或guava的objects equal(或者您可以自己滚动)。我甚至不会提到"表演"这个词,因为我怕有人用唐纳德·克努斯的书打我。
- 当使用在编辑代码时重新加载类的IDE时,可能有两个独立的编译枚举,即使它们应该是一个。那么,MyEnum.CONSTANT_ONE != MyEnum.CONSTANT_ONE是正确的。
- 请参阅有关类型安全性的其他答案:==在编译时接受类型兼容性检查
- @laszlok看起来是一个合理的论点,但是一旦你研究Enum#equals()的实现,你会发现这种论点是无效的。在Enum#equals()中,它只是执行==,这意味着,如果类被类加载器替换,==和equals都会失败(除非您为枚举编写自己的等号,这很少是明智的选择)。所以,在你提到的方面,equals并不比==好。
- @如果您在谈论"将枚举的使用替换为代码中的类",那么我看不到将基元类型的使用替换为类的区别。你不希望它自动工作,对吗?
- @Adriansum,这正是我要说的,你的例子就是,它和用类替换原语一样麻烦。在一个可能被重构为类的枚举上使用==并没有任何好的理由要求解决这个问题。
- @laszlok简单的编译时类型检查是选择==而不是equals()的原因。当然,这是个人对权重"编译时类型检查"和"用类替换枚举的容易性"的偏好,但我不能同意您继续提到"using==…"没有好的理由"
- 用类替换枚举并不常见。==与原语之间的比较是一致的,这对我来说很好。
- someEnum.someEnum?value.equals(a)也为"空安全"
- @阿德里安修我同意。轶事:有一次我们有了一个字符串常量X和一个方法调用X.equals(x)来处理字符串X。然后,X被重构为枚举。这个方法被打破了,但很长一段时间没人注意到。
- 从Java 7中,我发现对象是相等的最佳选择。
- @laszlok…枚举被类替换,此时,==不再保证是正确的,而equals继续无缝地、不无缝地工作;只有当这个新类或其层次结构中的任何超类都不重写equals()时,它才保证工作。
- @如果新的类或新的类层次结构实现了正确的相等(无论是通过重写还是通过继承对象中的实现),则santibailors是无缝的。最后,我同意Adrian Shum和上面提到的其他人的观点,最佳选择取决于所讨论的代码在多大程度上可能朝着所提出的不同方向发展。就我而言,在做了整整十年的Java之后,我还没有看到一个EnUM,它被重构成除了一个非常简单的数据结构之外的任何东西,而且这些枚举显然不会被重构,远远超过那些有一天可能会重构的枚举。
- 但问题是,枚举是最终的静态单例,因此应该遵循为最终静态对象使用所有大写字母的命名约定。如果将枚举重构为类,而对象不再是最终的静态对象,则会更改枚举/类的约定。
==能用于
enum吗?
是:枚举有严格的实例控件,允许您使用==来比较实例。以下是语言规范(我强调)提供的保证:
JLS 8.9 Enums
An enum type has no instances other than those defined by its enum constants.
It is a compile-time error to attempt to explicitly instantiate an enum type. The final clone method in Enum ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by the enum constants.
Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant. (The equals method in Enum is a final method that merely invokes super.equals on its argument and returns the result, thus performing an identity comparison.)
这个保证是足够强的,Josh Bloch建议,如果你坚持使用单模式,最好的实现方法是使用一个元素EDOCX1×7(参见:有效的Java第二版,项目3:用私有构造函数或枚举类型来执行SuntLon属性;在Singleton中也使用线程安全)。
==和
equals有什么区别?
需要提醒的是,一般来说,==不是equals的可行替代品。然而,如果是这样(如与enum一起),有两个重要的区别需要考虑:
==从不抛出
NullPointerException。
1 2 3 4 5
| enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color. BLACK); // runs fine
if (nothing. equals(Color. BLACK)); // throws NullPointerException |
==在编译时接受类型兼容性检查
1 2 3 4 5
| enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color. BLACK. equals(Chiral. LEFT)); // compiles fine
if (Color. BLACK == Chiral. LEFT); // DOESN'T COMPILE!!! Incompatible types! |
适用时是否应使用==?
bloch特别提到,对实例具有适当控制权的不可变类可以向客户机保证==是可用的。特别提到enum来举例说明。
Item 1: Consider static factory methods instead of constructors
[...] it allows an immutable class to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types provide this guarantee.
综上所述,在enum上使用==的理由是:
- 它起作用了。
- 它更快。
- 在运行时更安全。
- 它在编译时更安全。
- 回答不错,但是……1。有效:同意2.它更快:为Enums证明它:)3。它在运行时更安全:Color nothing = null;是imho bug,应该被修复,您的枚举有两个值,而不是三个(见Tom Hawtin的注释)4。在编译时更安全:好的,但是equals仍然返回false。最后,我不买它,我更喜欢equals()的可读性(见凯文的评论)。
- @帕斯卡:我同意null的论点是软弱的,因为null一开始就有争议(C.A.R.霍尔"十亿美元的错误"等)。另请参阅我的问题:stackoverflow.com/questions/2887761/…//I do think the compile-time type compatibility check is significant and than"silently failing"at run-time by return false。实际上,我并不关心速度优势,因为它不太可能具有重大意义;我只是重复布洛赫的话。
- 我承认我自己的论点"反对"编译时检查也很弱(编译时检查实际上可能是==的最佳论点,即使"无声失败"对我来说似乎太强)。关于布洛赫关于速度的观点,我当然不是说他错了,我只是不相信它适用于Enums(他写道May)。这就是为什么我认为向你的专业人士挑战是合法的:)但是你有我的+1,这仍然是一个很好的答案。
- 对Java来说,这是一个黑色的标记,有些人认为EDCOX1×1比EDCOX1(2)更可读。
- 它可以工作:直到需要用类替换枚举作为重构的一部分。祝您好运,找到所有使用==中断的代码。它更快:即使是真的(有问题的),也有关于提前优化的Knuth引用。在运行时更安全:"safe"不是第一个让人想到的词,如果使用==是唯一将您与nullPointerException分离的方法。编译时更安全:不是真的。它可以保护您避免比较错误类型这一非常基本的错误,但同样,如果这是您的程序员多么愚蠢的话,"安全"是您不能做到的一件事。
- "如果这是你的程序员多么愚蠢,"安全"是你不能做到的一件事。"——我不同意这句话。这就是类型检查的全部内容:在编译时甚至在代码运行之前防止"愚蠢的"错误。即使是聪明人也会犯愚蠢的错误,有些保证比承诺更好。
- 简单地说,编译时类型检查本身的优势就足以使用==进行枚举。没有理由支持将equals()用于枚举,除非人们提到"对象比较约定"。然而,考虑到枚举的特殊语义意义,我发现将其视为不同的东西并没有任何问题。您应该使用equals的唯一时间是,如果枚举被一些特殊的equals()逻辑覆盖,但我认为它很少是一个有效的移动。
- 如果您重新排序.equals,以便将常量与可能为空的值进行比较,它将永远不会抛出NullPointerException。所以我不确定你的论点是否相信,==永远不会抛出一个NPE,因为有很多方法可以写.equals,也不允许它抛出一个NPE。
- @Adriansum枚举等于是最终的。
- @Ymajoros有时你可以依靠编译器,有时你不能。一个聪明的程序员,以及他们的代码审查员,必须知道什么时候做是安全的。否则,没有多少"良好实践"能挽救你的一天。
- @拉兹洛克:当然,但是如果事情失败了,他们会的。为一些愚蠢的错误设置围栏总是件好事。对于不那么琐碎的bug,有足够的创作空间,让编译器在您尝试运行代码之前处理好这个bug。
- @laszlok很好地提醒我:p那么我没有理由使用.equals()来进行枚举。我仍然认为"equals()的参数使得将枚举更改为普通类更加容易"是脆弱的。如果采用这种论点,您甚至应该对所有原语类型使用((Object)primitiveVar).equals(anotherVar),而不是primitiveVar==anotherVar,因为您永远不知道何时要将原语类型的使用替换为类。
- 很明显(从讨论的长度来看,如果没有其他的话),我们在这里讨论的都是非常小的好处——否则会有一个明确的共识。我同意您不会经常用类替换枚举,但是您也不会经常比较错误的类型(即使是重构的结果)。也许正确的答案是"随便你想用什么就用什么,然后再回去工作"。:)
- 在现代的JVM中,"10" =="10"也是正确的,但我还是不推荐它。不过,如果我错了,请纠正我,你没有给出任何不适用于比较字符串的参数,对吗?
- 我使用Enums是因为我需要强类型和编译时检查。从这个角度来看,.equals()远远低于==。
- @您需要更新链接并相应地回答。因为它现在坏了。
- "10"=="10"不能保证是真的,这通常是正确的,因为Java优化了字符串。对于Enums,==是有意保证工作的。这不是意外或优化,而是您打算如何使用Enums。如果使用==或.equals实际上并不重要,但是不知道枚举是唯一的,那就是不了解工具的基本功能。
- 我不同意== never throws NullPointerException。如果使用整数并将其与"=="进行比较,则当整数为空时,可能会得到NullPointerException。将整数与"=="进行比较时,整数需要自动取消装箱。
使用==比较两个枚举值是可行的,因为每个枚举常量只有一个对象。
另一方面,如果您这样编写equals(),实际上不需要使用==编写空安全代码:
1 2 3 4 5 6 7 8
| public useEnums(SomeEnum a)
{
if(SomeEnum.SOME_ENUM_VALUE.equals(a))
{
...
}
...
} |
这是一个被称为"比较左边常量"的最佳实践,您肯定应该遵循这一点。
- 当.equals()生成字符串值时,我会这样做,但我仍然认为这是编写空安全代码的糟糕方法。我更希望有一个操作符(或一个方法,但我知道[null对象]。在JAVA中,由于DoT运算符的工作原理,它在Java中永远不会是零安全的),不管它使用的顺序是什么,它总是空的安全的。从语义上讲,"equals"操作符应该总是通勤的。
- 因为Java没有Groovy的安全导航操作符(EDCOX1,6),所以当与常量和TBH比较时,我将继续使用这个实践,我不觉得它很蹩脚,也许只是不太自然。
- null枚举通常是一个错误。您已经得到了所有可能值的枚举,这里是另一个!
- 除了显式注释为@Nullable的值外,我考虑将左边的常量作为反模式进行比较,因为它传播了关于哪些值可以或不能为空的模糊性。枚举类型几乎不应该是@Nullable,因此一个空值将是一个编程错误;在这种情况下,越早抛出npe,就越有可能在允许它为空的地方发现您的编程错误。所以"最佳实践…在枚举类型方面,您绝对应该遵循"显然是错误的"。
- 比较左边的常量,像尤达风格的最佳英语就是这样的最佳实践。
正如其他人所说,==和.equals()在大多数情况下都起作用。编译时的确定性,你没有比较完全不同类型的对象,其他人指出的是有效的和有益的,然而,比较两种不同编译时间类型对象的特定类型的bug也可以由FindBugs找到(并且可能通过Eclipse/ItLyLJ编译时检查),因此Java编译发现它并没有增加那么多额外的安全性。
然而:
事实上,==从未在我的头脑中抛出NPE是==的一个缺点。几乎不需要将enum类型作为null类型,因为您可能希望通过null表达的任何额外状态都可以作为附加实例添加到enum中。如果这是出乎意料的null,我宁愿有一个NPE而不是==,悄悄地评估为假。因此,我不同意它在运行时的观点;最好养成习惯,不要让enum值为@Nullable。
认为==更快的论点也是假的。在大多数情况下,您将对编译时类型为枚举类的变量调用.equals(),在这些情况下,编译器可以知道这与==相同(因为enum的equals()方法不能被重写),并且可以优化函数调用。我不确定编译器当前是否这样做,但是如果它没有,并且结果是Java中的一个性能问题,那么我宁愿修复编译器,而不是100000个Java程序员改变他们的编程风格以适应特定编译器版本的性能特征。
enums是物体。对于所有其他对象类型,标准比较是.equals(),而不是==。我认为对enums例外是危险的,因为最终可能会意外地将对象与==而不是equals()进行比较,特别是将enum重构为非枚举类时。在这种重构的情况下,从上面看它的工作点是错误的。为了让自己相信使用==是正确的,您需要检查所讨论的值是enum还是原语;如果它是非enum类,那么它是错误的,但很容易出错,因为代码仍然可以编译。如果使用.equals()是错误的,那么唯一的情况就是所讨论的值是原语;在这种情况下,代码不会编译,因此很难忽略。因此,.equals()更容易识别为正确的,并且对未来的重构更安全。
事实上,我认为Java语言应该有定义的=ON对象,在左边的值上调用.RealSalk(),并为对象标识引入一个单独的运算符,但这不是Java定义的方式。
总之,我仍然认为这些论点有利于使用.equals()作为enum类型。
- 关于第3点,我可以用enum作为switch的目标,所以它们有点特别。StringS也有点特别。
- switch语句的语法既不包含==也不包含.equals(),所以我不知道您的观点是什么。我的观点3.)是关于代码对读者的验证有多简单。只要switch语句编译,switch语句的相等语义是正确的。
下面是一个比较这两种情况的粗略计时测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import java.util.Date;
public class EnumCompareSpeedTest {
static enum TestEnum {ONE, TWO, THREE }
public static void main (String [] args ) {
Date before = new Date();
int c = 0;
for(int y =0;y <5;++y ) {
for(int x =0;x <Integer. MAX_VALUE;++x ) {
if(TestEnum. ONE. equals(TestEnum. TWO)) {++c ;}
if(TestEnum. ONE == TestEnum. TWO){++c ;}
}
}
System. out. println(new Date(). getTime() - before. getTime());
}
} |
对国际单项体育联合会逐一发表评论。以下是反汇编字节代码中上述两个比较:
1 2 3 4 5 6 7 8
| 21 getstatic EnumCompareSpeedTest$TestEnum. ONE : EnumCompareSpeedTest. TestEnum [19]
24 getstatic EnumCompareSpeedTest$TestEnum. TWO : EnumCompareSpeedTest. TestEnum [25]
27 invokevirtual EnumCompareSpeedTest$TestEnum. equals(java. lang. Object) : boolean [28]
30 ifeq 36
36 getstatic EnumCompareSpeedTest$TestEnum. ONE : EnumCompareSpeedTest. TestEnum [19]
39 getstatic EnumCompareSpeedTest$TestEnum. TWO : EnumCompareSpeedTest. TestEnum [25]
42 if_acmpne 48 |
第一个(等于)执行虚拟调用并测试堆栈中的返回布尔值。第二个(==)比较直接来自堆栈的对象地址。在第一种情况下,有更多的活动。
我和两个国际单项体育联合会进行了多次测试,每次一个。"=="的速度比以前快得多。
- 我怀疑编译器分支预测可能会使此测试无效。一个聪明的编译器会认识到这两个if语句的计算结果总是错误的,因此避免进行多次比较。一个真正聪明的编译器甚至可能认识到Y和X循环中的值对结果没有影响,并且优化了整个过程…
- 它可以,但肯定不会。我在答案中显示了编译器生成的字节码。
- 你们两个都很困惑。:-)分支预测在运行时工作,因此不同的字节代码不是超级相关的。然而,在这种情况下,分支预测对这两种情况都有同样的帮助。
- 谁在乎?除非你在视频游戏中对一个循环内的枚举进行数千次比较,否则额外的纳秒就没有意义了。
- 除非强制使用解释模式,否则字节码与性能非常无关。编写一个JMH基准来查看性能是否完全相同。
我更喜欢使用==而不是equals:
另外一个原因是,除了这里已经讨论过的其他原因之外,您可以引入一个bug而不必意识到它。假设您有这个枚举,它完全相同,但在分开的pacakges中(这不常见,但可能发生):
第一枚举:
1 2 3 4 5 6 7 8
| package first.pckg
public enum Category {
JAZZ,
ROCK,
POP,
POP_ROCK
} |
第二枚举:
1 2 3 4 5 6 7 8
| package second.pckg
public enum Category {
JAZZ,
ROCK,
POP,
POP_ROCK
} |
然后假设在item.category中使用与next相同的equals,即first.pckg.Category中的equals,但在没有意识到它的情况下,导入第二个枚举(second.pckg.Category)。
1 2 3 4
| import second.pckg.Category;
...
Category.JAZZ.equals(item.getCategory()) |
所以你会得到所有的false到期是一个不同的枚举,尽管你期望是真的,因为item.getCategory()是JAZZ。这可能有点难看。
因此,如果使用操作符==,则会出现编译错误:
operator == cannot be applied to"second.pckg.Category","first.pckg.Category"
1 2 3 4
| import second.pckg.Category;
...
Category.JAZZ == item.getCategory() |
在枚举的情况下,两者都是正确的!!
使用==以外的任何东西来比较枚举常量都是无稽之谈。这就像把class对象与equals对象进行比较——不要这样做!
然而,在Sun JDK 6U10和更早的版本中有一个讨厌的bug(bugid 6277781),出于历史原因,它可能很有趣。这个bug妨碍了对反序列化枚举正确使用==,尽管这可能是一个小问题。
枚举是为每个由public static final field(不可变)声明的枚举常量返回一个实例(如singleton)的类,以便可以使用==运算符检查它们的相等性,而不是使用equals()方法。
使用==枚举很容易工作的原因是,每个定义的实例也是一个单例。所以使用==进行身份比较总是有效的。
但是使用==是因为它与枚举一起工作意味着所有代码都与该枚举的使用紧密耦合。
例如:枚举可以实现接口。假设您当前使用的枚举实现了接口1。如果以后,有人更改它或引入一个新的类impl1作为同一接口的实现。然后,如果您开始使用impl1实例,您将有许多代码要更改和测试,因为以前使用了==。
因此,最好遵循被视为良好做法的做法,除非有任何合理的收益。
- 回答不错,但这里已经提到了。
- 嗯。此时,问题将是您是否在接口上使用==或等于。此外,还有各种各样的问题,即用可变实现替换不可变类型的实现是否真正明智。在你担心正当收益之前,先弄清楚什么是好的做法可能是明智的。(imho==是更好的做法)。
DR
另一种选择是Objects.equals效用方法。
1
| Objects.equals( thisEnum , thatEnum ) |
Objects.equals
equals operator == instead of .equals()
Which operator is the one I should be using?
第三个选项是在EDCOX1 14的实用工具类上添加到Java 7和以后的静态EDCOX1 OR 1方法。
例子
下面是一个使用Month枚举的示例。
1
| boolean areEqual = Objects.equals( Month.FEBRUARY , Month.JUNE ) ; // Returns `false`. |
效益
我发现这种方法有几个好处:
- 零安全性
- 都是空的吗?true
- 要么是空的?false
- 无抛掷NullPointerException的风险
- 紧凑、可读
它是如何工作的
Objects.equals使用的逻辑是什么?
请参见OpenJDK的Java 10源代码:
1
| return (a == b) || (a != null && a.equals(b)); |
简而言之,两者都有利弊。
一方面,如其他答案所述,使用==具有优势。
另一方面,如果您出于任何原因使用不同的方法(普通类实例)替换枚举,那么使用==会咬您。(BTDT)
- 这是不正确的。不能在枚举类上重写equals();它是final方法。这将破坏使用枚举的整个目的。stackoverflow.com/a/2964760/139010
- @Mattball谢谢。我应该试一下。我改写了答案。
我想补充聚原润滑油的答案:
我个人更喜欢平等。但它需要进行类型兼容性检查。我认为这是一个重要的限制。
要在编译时进行类型兼容性检查,请在枚举中声明并使用自定义函数。
1 2
| public boolean isEquals(enumVariable) // compare constant from left
public static boolean areEqual(enumVariable, enumVariable2) // compare two variable |
有了这个,您就获得了这两种解决方案的所有优势:NPE保护、易于读取的代码和编译时的类型兼容性检查。
我还建议为枚举添加未定义的值。
- 为什么这个解决方案比==更好?使用==,您可以获得NPE保护、易于读取的代码和编译时类型兼容性检查,并且可以在不编写任何类似自定义方法的情况下获得所有这些方法。
- 一个UNDEFINED值可能是一个好主意。当然,在Java 8中,您将使用EDCOX1 OR 13。
如果将原始类型与其类版本进行比较,则==可以抛出NullPointerException。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13
| private static Integer getInteger () {
return null;
}
private static void foo () {
int a = 10;
// Following comparison throws a NPE, it calls equals() on the
// non-primitive integer which is itself null.
if(a == getInteger ()) {
// Some code
}
} |
- 在这个问题上,范围相当明确,而原语类型不在范围内。
- @汤姆,这里的讨论误导了人们,说==永远不能扔下NPEs。这个问题有足够的答案,但如果像我这样花了2个小时来了解bug/feature的人读到了这个问题,这可以作为一个很好的参考。
- 如果你不忽略这个问题的主题,我就不能抛出一个NPE。即使你把这个答案放在这里,你认为有同样问题的人会通过搜索不同的东西找到这个答案吗?那个人需要搜索他们显然不使用的枚举。这个答案在这个问题上更有意义:stackoverflow.com/questions/7520432/&hellip;
我想明确强调一下==操作符和equals()方法之间的具体区别:
equals()方法用于检查所涉及的引用变量引用的对象的内容是否相同。
==运算符检查涉及的引用变量是否引用同一对象。
由实现类根据应用程序的需要提供这种差异。
否则,默认行为将由EDCOX1的27个类(爪哇)提供,如http://DOCS.Oracle .COM/JavaSe/1.5.0/DOCS/API/Java/Lang/Objult.HTML*Aythas(Java.Lang.Object)中所解释的:
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
- "equals()方法总是比较两个对象的内容"不,这不是真的。Object#equals()调用==。
- 问题不是如果==和等于等于等于-请删除
- MattBall这个答案是相当理论的,首先并不是关于Java是怎么做的。读完后,您可能会意识到检查两个枚举变量是否完全相同是没有意义的,因为您根本不在乎它们是否相同。你关心平等。
- 谁在乎Object类如何实现equals?我们说的不是Object,而是enum!
中间的枚举是一组常量整数。"=="与比较两个整数一样有效和正确。
- 在爪哇,枚举不只是一组常量整数。他们都在上课。
- 当然,但是"=="的使用归结为两个整数的比较。Java中的枚举给了您更多的可能性,可能没有语言具有如此广泛的枚举概念。
- 不,绝对不是。使用==操作符,可以比较两个类,换句话说,它们的内存地址。您没有比较ordinal()调用的值。
- 有什么区别,枚举引用了内存中的一个位置,所以您可以使用==。
- 它下面比较数字。
- 你也可以说字符是数字,因为计算机中的一切都是数字。这是语义上的胡说八道,对任何人都没有帮助。
- 相反,你不会帮助任何无知的人。用Java编写一个小程序,创建很多枚举,然后你就会明白我在写什么。