问:

我知道 Java 枚举被编译为具有私有构造函数和一堆公共静态成员的类。在比较给定枚举的两个成员时,我总是使用 .equals(),例如

public useEnums(SomeEnum a)
{if(a.equals(SomeEnum.SOME_ENUM_VALUE)){...}...
}

但是,我刚刚遇到了一些使用等号运算符 == 而不是 .equals() 的代码:

public useEnums2(SomeEnum a)
{if(a == SomeEnum.SOME_ENUM_VALUE){...}...
}

我应该使用哪个运算符?

答1:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

两者在技术上都是正确的。如果您查看 .equals() 的源代码,它只是遵循 ==。

但是,我使用 ==,因为它是 null 安全的。

使用 == 而不是 equals 的另一个参数是类型的编译时检查。 myEnum.MY_CONSTANT.equals("Some String") 会编译而 myEnum.MY_CONSTANT == "Some String" 不会,因为 "Some String" 不是同一类型,编译器可以预先确定它

答2:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

== 可以用在枚举上吗?

是:枚举具有严格的实例控制,允许您使用 == 来比较实例。这是语言规范提供的保证(我强调):

JLS 8.9 枚举枚举类型除了由其枚举常量定义的实例之外没有实例。尝试显式实例化枚举类型是编译时错误。 Enum 中的 final clone 方法确保了枚举常量永远不会被克隆,而序列化机制的特殊处理确保了不会因为反序列化而创建重复的实例。禁止枚举类型的反射实例化。这四件事一起确保枚举类型的实例不存在超出枚举常量定义的实例。因为每个枚举常量只有一个实例,所以在比较两个对象引用时,如果知道其中至少一个引用了枚举常量,则允许使用 == 运算符代替 equals 方法。 (Enum 中的 equals 方法是 final 方法,它仅在其参数上调用 super.equals 并返回结果,从而执行身份比较。)

这个保证足够强大,Josh Bloch 建议,如果你坚持使用单例模式,实现它的最佳方式是使用单元素 enum(参见:Effective Java 2nd Edition,Item 3:使用私有构造函数或枚举类型强制执行单例属性;同样Thread safety in Singleton)

== 和 equals 有什么区别?

提醒一下,需要说明的是,== 通常不是 equals 的可行替代品。但是,如果是(例如使用 enum),则需要考虑两个重要的区别:

== 从不抛出 NullPointerException

enum Color { BLACK, WHITE };Color nothing = null;
if (nothing == Color.BLACK);      // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException

== 在编译时接受类型兼容性检查

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 被特别提及以举例说明。

第 1 项:考虑静态工厂方法而不是构造函数 […] 它允许不可变类保证不存在两个相等的实例:a.equals(b) 当且仅当 a==b 时。如果一个类做出了这种保证,那么它的客户端可以使用 == 运算符而不是 equals(Object) 方法,这可能会提高性能。枚举类型提供了这种保证。

总而言之,在 enum 上使用 == 的论据是:

有用。

它更快。

它在运行时更安全。

在编译时更安全。

答3:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

使用 == 比较两个枚举值是可行的,因为每个枚举常量只有一个对象。

附带说明一下,如果您像这样编写 equals(),实际上不需要使用 == 来编写 null 安全代码:

public useEnums(final SomeEnum a) {if (SomeEnum.SOME_ENUM_VALUE.equals(a)) {…}…
}

这是您绝对应该遵循的称为 Compare Constants From The Left 的最佳做法。

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

null 枚举通常是一个错误。您已经获得了所有可能值的枚举,这是另一个!

比较左侧的常量是一种最佳实践,例如尤达风格的最佳英语。

答4:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

正如其他人所说,== 和 .equals() 在大多数情况下都有效。您没有比较其他人指出的完全不同类型的对象的编译时间确定性是有效和有益的,但是 FindBugs 也可以发现比较两种不同编译时间类型的对象的特定错误(可能由Eclipse/IntelliJ 编译时检查),因此发现它的 Java 编译器不会增加太多额外的安全性。

然而:

== 在我的脑海中从来没有抛出 NPE 的事实是 == 的一个缺点。几乎不需要枚举类型为 null,因为您可能想通过 null 表达的任何额外状态都可以作为附加实例添加到枚举中。如果它意外地为空,我宁愿有一个 NPE 而不是 == 默默地评估为假。因此,我不同意运行时更安全的观点;最好养成永远不要让枚举值成为@Nullable 的习惯。 == 更快的论点也是虚假的。在大多数情况下,您将对编译时类型为枚举类的变量调用 .equals(),在这些情况下,编译器可以知道这与 == 相同(因为枚举的 equals() 方法不能覆盖)并且可以优化函数调用。我不确定编译器当前是否这样做,但如果没有,并且结果证明这是 Java 整体的性能问题,那么我宁愿修复编译器,也不愿让 100,000 名 Java 程序员改变他们的编程风格以适应特定编译器版本的性能特征。枚举是对象。对于所有其他对象类型,标准比较是 .equals(),而不是 ==。我认为对枚举进行例外处理是很危险的,因为您最终可能会意外地将 Objects 与 == 而不是 equals() 进行比较,尤其是当您将枚举重构为非枚举类时。在这种重构的情况下,上面的 It works 点是错误的。为了说服自己使用 == 是正确的,您需要检查所讨论的值是枚举还是原始值;如果它是一个非枚举类,那将是错误的,但很容易错过,因为代码仍然可以编译。使用 .equals() 错误的唯一情况是所讨论的值是原始值;在这种情况下,代码将无法编译,因此更难错过。因此, .equals() 更容易识别为正确的,并且对未来的重构更安全。

我实际上认为 Java 语言应该在 Objects 上定义 == 以在左侧值上调用 .equals() ,并为对象标识引入一个单独的运算符,但这不是 Java 的定义方式。

总之,我仍然认为这些论点支持将 .equals() 用于 enum 类型。

答5:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

我更喜欢使用 == 而不是 equals:

除了这里已经讨论过的其他原因之外,其他原因是您可能会在没有意识到的情况下引入错误。假设你有这个完全相同的枚举,但在分开的包中(这并不常见,但它可能会发生):

第一个枚举:

package first.pckgpublic enum Category {JAZZ,ROCK,POP,POP_ROCK
}

第二个枚举:

package second.pckgpublic enum Category {JAZZ,ROCK,POP,POP_ROCK
}

然后假设您在 item.category 中使用了等号,即 first.pckg.Category,但您导入了第二个枚举 (second.pckg.Category) 而不是第一个枚举,但没有意识到:

import second.pckg.Category;
...Category.JAZZ.equals(item.getCategory())

所以你总是会得到 false due is a different enum 尽管你期望 true 因为 item.getCategory() 是 JAZZ。而且可能有点难以看到。

因此,如果您改为使用运算符 ==,您将遇到编译错误:

运算符 == 不能应用于“second.pckg.Category”、“first.pckg.Category”

import second.pckg.Category;
...Category.JAZZ == item.getCategory() 

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

这是一项重要的检查,值得一提

答6:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

tl;博士

另一个选项是 Objects.equals 实用程序方法。

Objects.equals( thisEnum , thatEnum )

Objects.equals 用于空安全

等于运算符 == 而不是 .equals()

我应该使用哪个运算符?

第三个选项是在 Objects 实用程序类 added to Java 7 及更高版本中找到的静态 equals 方法。

例子

下面是使用 Month 枚举的示例。

boolean areEqual = Objects.equals( Month.FEBRUARY , Month.JUNE ) ;  // Returns `false`.

好处

我发现这种方法有几个好处:

Null-safety Both null ➙ true 要么 null ➙ false 没有抛出 NullPointerException 的风险

两者都为空➙真

要么为空➙假

没有抛出 NullPointerException 的风险

紧凑,可读

这个怎么运作

Objects.equals 使用的逻辑是什么?

从 OpenJDK 的 Java 10 source code 中亲自查看:

return ( a == b ) || ( a != null && a.equals( b ))
;

您所说的所有好处都不适用于 Objects.equals 与 ==。 == 在上述场景中的行为与 Objects.equals 完全相同。

答7:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

这是一个粗略的时间测试来比较两者:

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 保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务--huntsbot.com声纳规则之一是 Enum values should be compared with "=="。原因如下:使用 equals() 测试枚举值的相等性是完全有效的,因为枚举是一个对象,每个 Java 开发人员都知道 == 不应该用于比较对象的内容。同时,在枚举上使用 ==:提供与 equals() 相同的预期比较(内容)比 equals() 提供编译时(静态)检查而不是运行时检查更安全由于这些原因,使用== 应该优先于 equals()。最后但并非最不重要的一点是,枚举上的 == 可以说比 equals() 更具可读性(不那么冗长)。# 答9:
> 保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务--huntsbot.com在枚举的情况下,两者都是正确和正确的!# 答10:
> huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。使用 == 以外的任何东西来比较枚举常量都是无稽之谈。就像 comparing class objects with equals - 不要这样做!但是,由于历史原因,Sun JDK 6u10 及更早版本中存在一个令人讨厌的错误 (BugId 6277781)。这个错误阻止了在反序列化枚举上正确使用 ==,尽管这可以说是一种极端情况。# 答11:
> huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。枚举是为 public static final field 声明的每个枚举常量(不可变)返回一个实例(如单例)的类,因此 == 运算符可用于检查它们的相等性,而不是使用 equals() 方法原文链接:[https://www.huntsbot.com/qa/BBWl/comparing-java-enum-members-or-equals?lang=zh_CN&from=csdn](https://www.huntsbot.com/qa/BBWl/comparing-java-enum-members-or-equals?lang=zh_CN&from=csdn)> 打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!

比较 Java 枚举成员:== 或 equals()?相关推荐

  1. java 注解 enum_13 Java枚举和注解

    Java枚举 在某些情况下,一个类的对象是有限而且固定的.例如季节类,只能有 4 个对象. 当类的对象是有限时,就应该使用枚举,而不使用普通类.(枚举对象是单例模式) 枚举的属性 实现接口的枚举类 例 ...

  2. Java 枚举7常见种用法

    1.Java1.5引入了新的类型--枚举.在 Java 中它虽然算个"小"功能,却给我的开发带来了"大"方便. 用法一:常量 在JDK1.5 之前,我们定义常量 ...

  3. Java枚举类型(enum)详解

    文章目录 理解枚举类型 枚举的定义 枚举实现原理 枚举的常见方法 Enum抽象类常见方法 编译器生成的Values方法与ValueOf方法 枚举与Class对象 枚举的进阶用法 向enum类添加方法与 ...

  4. java枚举对象作用_浅析Java编程中枚举类型的定义与使用

    定义枚举类型时本质上就是在定义一个类,只不过很多细节由编译器帮您补齐了,所以某些程度上,enum关键字的 作用就像是class或interface. 当您使用"enum"定义枚举类 ...

  5. java 枚举 面试题_java 枚举(面试题)基本知识总结即简例

    枚举 jdk1.5以后引入 关键字enmu enmu Apple{     Jonathan,   GoldenDel, RedDel } 枚举常量被隐式声明为Apple的公有静态final成员 枚举 ...

  6. Java枚举(Enum)类型使用的正确姿势

    关于Java Enum的介绍及原理参见 Java枚举(Enum)类型的基本介绍与原理探求 Enum类型的基本使用 定义一个枚举类的主要作用就是在逻辑代码中对某个变量的值进行比较.同样以季节的枚举类Se ...

  7. Java枚举(Enum)类型的基本介绍与原理探求

    Enum枚举类型 Enum的全写是Enumeration,这个词的翻译是列举.逐条陈述.细目.在程序语言中,枚举类型是一种特殊的数据类型(常用的数据类型比如字符串.整型),这种数据类型的变量值限定在固 ...

  8. Java枚举深入理解以及HttpStatus类的使用

    1枚举 1.1枚举基础 由于每个程序员在开始编程时一般会首先学习C/C++,然后再学习Java,在C++中枚举是可以定义枚举值为特定的整数的,但这在Java中却没有得到支持,大概C/C++中的枚举代表 ...

  9. Java培训:Java枚举是什么

    1.什么是枚举? 枚举是JDK5引入的新特性.在某些情况下,一个类的对象是固定的,就可以定义为枚举.在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全.枚举有以下特点: ①Java中枚举和类. ...

最新文章

  1. chrome vue 未响应_VUE数据响应式
  2. C# 中文件路径的操作
  3. 微软想让你跟机器人说句话就把事办了
  4. mysql浅拷贝_深拷贝与浅拷贝
  5. jQuery EasyUI DataGrid Checkbox 数据设定与取值
  6. 超时尚的UI电子商务PSD分层模板,临摹学习必备
  7. lolcat :一个在 Linux 终端中输出彩虹特效的命令行工具
  8. ubuntu 16.04无法正常关机、重启
  9. MySQL数据库备份
  10. java ipa签名_iOS苹果应用IPA一键签名工具及重签教程
  11. 360极速浏览器代理设置无效问题
  12. IDEA 文件对比功能图解
  13. 北京市小牛电动车选购指南
  14. 采购入库单部分结算时是否自动暂估 参数 是的情况下
  15. 移动智能终端安全防护 笔记
  16. 面试总结 -记周六校招笔试
  17. 魔兽地图服务器修改,如何修改魔兽地图(傻瓜版)
  18. 你好!Docker【概念+源码+保姆式教程】
  19. 如何用记事本写Java程序
  20. oracle表独立数据文件,oracle表空间及数据文件

热门文章

  1. allegro设置差分线
  2. 模拟cmos集成电路(6)
  3. 排污单位门禁、视频、参数监控联网数据采集传输仪
  4. idea开启远程调试
  5. 无传感器永磁同步电机电机自适应自抗扰ADRC控制策略
  6. (转)一致性哈希算法原理
  7. C语言中的自定义函数
  8. 华硕笔记本U盘装系统教程
  9. 【一个项目开发的完整流程】
  10. CornerNet代码学习之pytorch多线程