【问题标题】:Java: Understanding enum betterJava:更好地理解枚举
【发布时间】:2014-06-25 14:34:16
【问题描述】:

请帮助我更好地理解这个枚举类。

public enum TryMe {

    A("A", "Description of A"), 
    B("B", "Description of B");

    private String a;
    private String b;

    private TryMe(String a, String b) {
        this.a = a;
        this.b = b;
    }

    //Getter and Setter for 'a' and 'b'

}

当我包含在 Hibernate Entity 类中时会发生什么?
实体类对应的数据库列需要一个值为“A”或“B”的字符串。
String 值将如何传递?

【问题讨论】:

  • 不,没有二传手。你绝对应该将'a'和'b'声明为'final'!
  • 从技术上讲,您不需要枚举构造函数中的 private 关键字 - 无论如何,所有枚举构造函数都隐含 private,尝试声明是编译器错误他们是别的什么。是否包含它实际上取决于个人喜好,但我知道有些人喜欢在其中包含它。
  • 枚举在代替标准单例模式时也非常有用。 @see Josh Bloch 的“Effective Java”informit.com/articles/article.aspx?p=1216151&seqNum=3

标签: java hibernate enums


【解决方案1】:

任何枚举都可以通过其名称进行唯一标识。这些常量名称(在您的情况下为 AB)由 Java 编译器编译为 static 字段,其中每个字段都包含枚举类型的实例。这样,枚举实例在整个应用程序(或更准确地说,类加载器)中是唯一的。在任何时间点都无法更改这些字段,即使使用反射也是如此。

因此,枚举不能被 Hibernate 序列化,并且不可能在枚举中持久化状态更改(无论如何您都应该避免。)它们只能被引用,这就是 Hibernate 所做的。 Hibernate / JPA stores enums therefore as either:

  • 通过它们的常量名称(AB
  • 按序号 (0, 1)

后一种方法的问题在于,您不能再在不破坏存储值的情况下更改常量值的顺序。如果您在A 之前声明了B,那么您的所有数据库表示都将被关闭。这很可能会破坏您的应用程序,这就是建议使用第一种存储方法的原因。

当从 Hibernate 加载一个值时,它将返回枚举类中名为 AB 的字段的值。如果您的 JVM 实例在此期间确实重新启动,则对枚举字段的任何更改都将因此丢失。

如果你仔细想想,这也很有意义。任何枚举状态都是全局的,您无法保存不同的状态,例如 A,并且一旦从数据库加载两个不同的值,它就会在不同的状态下被表示两次。这将打破枚举的唯一性契约。

【讨论】:

    【解决方案2】:

    不会传递字符串值,只会传递成员的名称。 由于这是一个固定成员,所以你总是可以通过枚举的键或索引来抓取值,然后获取字符串值

    见jpa的@Enumerated注解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-17
      • 2021-12-03
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 2011-10-27
      相关资源
      最近更新 更多