【问题标题】:What does Java compile an enumeration down to?Java 将枚举编译成什么?
【发布时间】:2011-09-01 21:29:38
【问题描述】:

我和一位同事讨论了 Java 如何表示枚举。我的印象是它们严格来说是像 C/C++ 这样的整数。或者,如果您添加行为(类型安全枚举),它会被包装在一个类中。他相信如果它足够小,Java 会压缩到一个字节。

但是,我在 Oracle 网站上找到了这个:

Java 编程语言的枚举比其他语言中的枚举要强大得多,后者只不过是美化的整数。新的枚举声明定义了一个成熟的类(称为枚举类型)。

我认为它们是真实的对象。如果是这样,有没有办法优化它们以节省空间?

谢谢

编辑:正如对 Jon 的回答的评论中提到的,我追求的是 Enum 的序列化大小。

【问题讨论】:

  • 如果您需要“优化 Java 枚举以节省空间”,那么您做错了。具体来说,如果您的 Enums 占用了太多空间,那么您的 Enums 似乎可能太多了。
  • 并不是我们的枚举太多。这是我们打算传递带有枚举的对象。因此,结构越小,发送的效率就越高。或者这就是想法......
  • 如果您使用 Enums 来定义类型(例如,这是一个 Blammy 报告,因此它的 type = enum.Blammy)您可能会考虑使用多态性(例如,BlammyReport 类扩展 ...) .
  • 是的,但是当对象不再彼此不同时会发生什么?那么BlammyReport和TPSReport是一样的,只是类型不同,需要区别对待?
  • 多态性的胜利!相同的功能可以在父类中实现,但使用类类型方便处理差异。

标签: java optimization enums compilation java-6


【解决方案1】:

不,Java 枚举值确实是对象。它们可以具有字段、方法等 - 以及基于每个值的方法的不同实现。但是,它们只有一组固定的 - 这不像您自己创建枚举类型的实例;有效值集是在类型初始化时创建的。除非您有 大量 个枚举值,否则您几乎不需要考虑优化。

请注意,当您在逻辑上考虑一组枚举值时, 很容易实现的一点优化是使用EnumSet。这使用位模式来基本有效地表示集合。

(请注意,这里的 C# 比 Java 更接近 C++ - 遗憾的是,C# 枚举不是面向对象的。叹息。)

编辑:枚举值由 name 根据the documentation 进行序列化:

已向序列化添加支持以处理枚举类型,这是 5.0 版中的新增功能。序列化枚举实例的规则与序列化“普通”可序列化对象的规则不同:枚举实例的序列化形式仅包含其枚举常量名称以及标识其基本枚举类型的信息。反序列化行为也不同——类信息用于查找适当的枚举类,并使用该类和接收到的常量名称调用 Enum.valueOf 方法,以获得要返回的枚举常量。

如果你真的想要一个小的序列化形式,你可能应该避开 Java 的内置序列化,它相对冗长(并且对版本控制问题非常敏感)。有各种各样的选择——我最了解的一种是Protocol Buffers,它确实将枚举值序列化为整数。

【讨论】:

  • 这里引用 Josuha Bloch 的一句话“从表面上看,这些枚举类型可能与其他语言的枚举类型相似,例如 C、C++ 和 C#...Java 的枚举类型是成熟的类"
  • EnumSet 非常简洁,但可以处理不同的问题。我们所关心的空间问题更多地与序列化最小的对象有关。但是,如果我们将枚举剥离为准系统,这似乎是一个有争议的问题。
  • @Tony:你应该提到你是在 serialization 大小之后 - 我偷偷怀疑枚举值无论如何都会被序列化为它们的序数值。
  • @Tony:假设你故意不接受答案,你还要找什么?
  • @Tony:我已经更新了我的答案。事实证明,序列化是按名称而不是序数值(请参阅参考文档) - 但如果您使用 Java 的二进制序列化并且大小是一个重要的考虑因素,那么无论如何您都应该考虑替代方案。
猜你喜欢
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多