【问题标题】:Overriding Enum#toString not desirable?重写 Enum#toString 不可取?
【发布时间】:2012-06-06 20:49:18
【问题描述】:

我刚刚注意到Enum#toString javadoc 状态(强调我的):

返回此枚举常量的名称,包含在声明中。 此方法可能会被覆盖,尽管它通常不是必要的或可取的。当存在更“程序员友好”的字符串形式时,枚举类型应覆盖此方法。

默认情况下,toString() 和 name() 返回相同的内容,因此即使 toString 已被覆盖,仍然可以通过 name() 方法访问枚举的名称。

有人知道为什么不希望覆盖 Enum#toString 吗?

编辑:供参考,name() 的 javadoc(重点与原文相同):

返回此枚举常量的名称,与其枚举声明中的声明完全相同。 大多数程序员应该优先使用 toString() 方法,因为 toString 方法可能会返回一个对用户更友好的名称。此方法主要设计用于正确性取决于获取确切名称的特殊情况,该名称不会因版本而异。

【问题讨论】:

  • 可能需要的一个示例可能是存在一个现有的编码约定,即枚举值应以所有大写字母命名(例如,VALUE),但这对用户来说看起来很笨重,所以 toString 可以实现返回 name.toLowerCase() 或其他一些案例操作。
  • 我的用例是枚举表示向用户显示的一组选项(例如在JComboBox 中)。我的第一个倾向是覆盖 toString 以为用户提供本地化显示名称,但 javadoc 建议只覆盖以获得更好的“程序员友好”字符串形式,这让我相信它不适合用作“用户友好”的形式。但是,name() 的 javadoc 中的注释表明 toString() 旨在返回一个 user 友好的名称,这使我相信 toString 的 javadoc 应该相同“用户友好" 代替。

标签: java enums


【解决方案1】:

使用枚举,您有一组特定的常量值。当为该枚举调用 toString 方法时,通常会期望返回名称,因此覆盖 toString 方法会返回一些意想不到的结果。

【讨论】:

  • 对。当他们说不可取时,他们的意思可能不是“你真的不应该这样做”,而是“停下来想一想你是否真的有充分的理由这样做”。这一切都归结为为客户提供最少令人困惑的行为。
  • 如果我真的想得到声明的枚举值的名称,我调用name,而不是toString。
  • 是的,你可以做任何一个,但由于 toString 默认为 name,大多数人希望 name 是返回值......特别是因为枚举的全部意义在于有一组常量值.通过直接调用 name,您可以确保获得预期的结果。如果您需要其他格式或其他格式,您当然可以覆盖 toString。
  • 不过,能够将枚举值直接传递给 println 并自动将其转换为字符串表示形式(通过 toString),这很好。
【解决方案2】:

如果您的枚举比它们的名称更复杂,例如如果它们包含私有字段,则可以覆盖 toSting() 以打印这些字段,并更好地解释枚举字段,而不仅仅是其名称。

【讨论】:

  • 我的问题正好相反:为什么不希望做你描述的事情?
  • 好吧,既然文档说它通常不是必要的或可取的,我认为除非你的枚举中有一个“复杂”的结构,否则它是不必要的。我不觉得文档的作者说“你不应该覆盖,这是一个坏主意”
【解决方案3】:

我认为这里的“理想”一词的含义存在一些混淆。 javadoc 基本上说了两次同样的事情:覆盖 toString() 通常不是枚举工作所必需的,因此这样做没有用(可取)。

所以回答你的问题:如果:A) 你知道你永远不必显示枚举名称的字符串表示,或者 B ) 如果需要,默认字符串表示足以识别枚举。

【讨论】:

  • 我不是以英语为母语的人 - 我认为不可取的意思是“应该避免”。你的解释是有道理的。
  • 是的,我认为为了更清楚,您可以将“desirable”替换为“recommended”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多