Java 存储常量(无论是枚举还是数据库表)的最佳方法要牢记国际化

Java 存储常量(无论是枚举还是数据库表)的最佳方法要牢记国际化,java,database,enums,internationalization,constants,Java,Database,Enums,Internationalization,Constants,我有很多静态/常量数据要存储,这些数据也相互关联。我可以使用批次枚举相互引用,形成树或图形。或者简单地使用表或数据库枚举并在其中存储值,然后创建相应的类和相应的关系。我掌握的数据是不变的,肯定不会改变。在不久的将来,我可能还要考虑国际化问题。我将使用这个常量数据作为各种其他数据的过滤器 我很想使用枚举,因为它在默认情况下给了我不变性,但是看到数据之间关系的复杂性,就像我可能不得不牺牲继承一样,我也不太担心枚举。从数据库和国际化中填充这些枚举类可能会稍微复杂一些。在稍后的阶段,希望它能够扩展并轻松

我有很多静态/常量数据要存储,这些数据也相互关联。我可以使用批次枚举相互引用,形成树或图形。或者简单地使用表或数据库枚举并在其中存储值,然后创建相应的类和相应的关系。我掌握的数据是不变的,肯定不会改变。在不久的将来,我可能还要考虑国际化问题。我将使用这个常量数据作为各种其他数据的过滤器

我很想使用枚举,因为它在默认情况下给了我不变性,但是看到数据之间关系的复杂性,就像我可能不得不牺牲继承一样,我也不太担心枚举。从数据库和国际化中填充这些枚举类可能会稍微复杂一些。在稍后的阶段,希望它能够扩展并轻松地接受复杂性是我所关注的领域,因为我不想从中途返回

---更新---

我没有看到相互关联的枚举示例,其中包含引用其他枚举的复杂类型字段。在这种情况下,当数据为常量时,枚举可以替换类。 有没有客观的方法来看待这个问题

为了更好地理解,我有如下类似的分类。

根据经验,只有当值的更改速度可能快于代码发布周期,并且可能或可能有非我的人要更改它们时,我才涉及数据库。使代码依赖于正在运行(且可用)的数据库意味着,当某些DBA关闭数据库进行维护时,您的应用程序将无法启动。

根据经验,我只在值的更改速度可能快于代码发布周期时才涉及数据库,当一个不是我的人有可能改变他们的时候。使代码依赖于正在运行(且可用)的数据库意味着,当某些DBA关闭数据库进行维护时,您的应用程序将无法启动。

虽然这个问题对于堆栈溢出来说可能过于广泛,但还是有一些想法

枚举类型 您可能不完全了解Java中的枚举功能。请参阅,然后查看类文档

枚举是一个类,一个常规Java类,一个子类。唯一特别的是,语法糖可以自动实例化您定义和命名的静态实例。否则,它们是普通类:

  • 枚举可以携带成员变量
  • 枚举可以有构造函数,并且可以将参数传递给这些构造函数
  • 枚举可以提供其他方法,并且可以向这些方法传递参数
  • 甚至可以将一个枚举的实例作为参数传递给另一个枚举实例的方法,就像将枚举实例传递给其他非枚举类的实例一样。每个枚举实例只是一个对象,简单明了,保存为枚举定义类上的静态引用
例如:

public enum Food { HERBIVORE, OMNIVORE, CARNIVORE ; }  // Syntactic sugar for automatically instantiating these named static instances of this class type.
……还有

public enum Animal {
    RABBIT( Food.HERBIVORE ) , 
    DOG( Food.OMNIVORE ) , 
    CAT( Food.CARNIVORE ) ;  

    // Member variables.
    public Food eats ; 

    // Constructor
    Animal( Food foodType ) {
        this.eats = foodType ;  // Assign an instance of another enum to this instance of this enum.
    }

}
枚举的局限性 虽然比其他语言更强大、更有用,但也存在一些局限性

编译时 首先,枚举是在编译时定义的。如果您的值在运行时发生更改,可能需要添加或删除项,则枚举不合适

永久记忆 此外,枚举是静态的。这意味着当第一次使用时,该枚举类的所有对象都会立即实例化,并在整个应用程序执行过程中保存在内存中。所以,在程序结束之前,它们永远不会从内存中退出。因此,拥有大量的基因可能会对记忆造成负担

了解您可以收集枚举实例。有关枚举实例的快速执行和低内存使用率集合,请参见
EnumSet
EnumMap
类。搜索堆栈溢出,了解有关此主题的更多内容。请注意,每个枚举都带有一个
values()
方法,该方法返回其值的数组,但此方法是无效的

至于您提到的继承,根据定义,您的枚举是类的子类。因此,它们不能从您可能想到的任何其他类继承,因为Java不支持。枚举可以实现一个或多个接口。在Java的更高版本中,继承可以通过新的默认方法携带实现代码,所以您可以通过这种方式传递一些代码

国际化 这似乎是一个正交问题。您可以在枚举上添加一个方法,以生成其值的本地化
字符串
表示形式。作为示例,请参见和枚举方法

数据库 如果您想在运行时动态定义您的值,或者您有无数的值,那么数据库就是一种选择。一个严肃的数据库,如设计用于管理内存、处理并发性和高效执行

您甚至可以将枚举与数据库相结合。例如,本地化。您可能在编译时定义了枚举值,但它们的
getDisplayName
方法会在数据库中查找法文或阿拉伯文翻译。数据库中的转换值可以在运行时通过JDBC运行SQL
INSERT
UPDATE
命令来更新

递归层次关系
如果您试图表示任意深度层次结构的关系,那么这是一个完全不同的主题,我在这里将不讨论它,只说它通常是通过递归实现的。搜索堆栈溢出和其他源以了解更多信息

虽然这个问题对于堆栈溢出来说可能过于宽泛,但还是有一些想法

枚举类型 您可能不完全了解Java中的枚举功能。请参阅,然后查看类文档

枚举是一个类,一个常规Java类,一个子类。唯一特别的是,语法糖可以自动实例化