Java:Enum vs. Int

Fly*_*ynn 58 java enums

在Java中使用标志时,我看到了两种主要方法.一个使用int值和一行if-else语句.另一种是使用枚举和case-switch语句.

我想知道在使用enums和ints for flags之间内存使用和速度方面是否存在差异?

Boh*_*ian 126

双方intsenums可以同时使用开关或IF-THEN-ELSE和内存使用情况也是最小的两个,而速度是类似的-有关于你提到的点之间没有显著差异.

但是,最重要的区别是类型检查.Enums被检查,ints不是.

考虑以下代码:

public class SomeClass {
    public static int RED = 1;
    public static int BLUE = 2;
    public static int YELLOW = 3;
    public static int GREEN = 3; // sic

    private int color;

    public void setColor(int color) {
        this.color = color;
    }   
}
Run Code Online (Sandbox Code Playgroud)

虽然许多客户会正确使用这个,

new SomeClass().setColor(SomeClass.RED);
Run Code Online (Sandbox Code Playgroud)

没有什么可以阻止他们写这个:

new SomeClass().setColor(999);
Run Code Online (Sandbox Code Playgroud)

使用该public static final模式有三个主要问题:

  • 问题发生在运行时,而不是编译时,因此修复起来会更加昂贵,并且更难找到原因
  • 你必须编写代码来处理错误的输入 - 通常if-then-else是最终的else throw new IllegalArgumentException("Unknown color " + color);- 再次昂贵
  • 没有什么能阻止常量的冲突 - 上面的类代码即使编译也会编译,YELLOW并且GREEN两者具有相同的值3

如果您使用enums,则解决所有这些问题:

  • 除非您传入有效值,否则您的代码将无法编译
  • 不需要任何特殊的"错误输入"代码 - 编译器会为您处理
  • 枚举值是唯一的


duf*_*ymo 10

内存使用和速度不是重要的考虑因素.你无论如何都无法衡量差异.

我认为枚举在应用时应该是首选的,因为强调所选择的值组合在一起并构成一个封闭的集合.可读性也得到了很大改善.使用枚举的代码比分散在整个代码中的杂散int值更自我记录.

喜欢枚举.


the*_*ing 10

您甚至可以使用Enums来替换那些按位组合标记 int flags = FLAG_1 | FLAG_2;

相反,您可以使用类型安全的EnumSet:

Set<FlagEnum> flags = EnumSet.of(FlagEnum.FLAG_1, FlagEnum.FLAG_2);

// then simply test with contains()
if(flags.contains(FlagEnum.FLAG_1)) ...
Run Code Online (Sandbox Code Playgroud)

文档声明这些类在内部被优化为位向量,并且实现应该足够好以替换基于int的标志.


Tim*_*Tim 7

你会看到一些使用intflags而不是a的代码的原因之一enum是Java在Java 1.5之前没有枚举

因此,如果您正在查看最初为旧版Java编写的代码,那么该int模式是唯一可用的选项.

int在现代Java代码中,使用标志的地方数量非常少,但在大多数情况下enum,由于它们提供的类型安全性和表现力,您应该更喜欢使用标志.

在效率方面,它将取决于它们的确切使用方式.JVM非常有效地处理这两种类型,但对于某些用例,int方法可能稍微有效(因为它们被处理为原始而不是对象),但在其他情况下,枚举会更有效(因为它不会'需要去扔拳击/拆箱).

您很难找到效率差异在现实世界的应用程序中以任何方式显而易见的情况,因此您应该根据代码的质量(可读性和安全性)做出决定,这将导致您99%的时间使用枚举.

  • 应该注意的是,在早期版本中,通过*手动*创建类似枚举的类(具有私有构造函数,一些"静态最终"字段和适当的序列化魔法),可以在Java 5+中实现"枚举"所具有的相同效果.确保唯一性).它很少使用*,但谷歌搜索"类型安全的枚举Java 1.4"可能会带来一两个教程.`enum`是"仅仅"的语法糖. (2认同)