为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕标5832272 2021-07-12 10:39:52
我有很多要存储的静态/常量数据,这些数据也相互关联。我可以使用很多枚举相互引用形成树或图形。或者简单地使用表或数据库枚举并在其中存储值并创建相应的类和相应的关系。我拥有的数据是不变的,肯定不会改变。在不久的将来,我可能还必须考虑国际化。我将使用这个常量数据作为各种其他数据的过滤器。我很想使用枚举,因为它默认为我提供了不变性,但是看到数据之间关系的复杂性,就像我可能不得不牺牲继承一样,我也不太担心枚举。从数据库和国际化填充这些枚举类可能有点棘手。在后期,希望它能够轻松扩展并接受复杂性是关注的领域,因为我不想从中途恢复。!- -更新 - -我还没有看到彼此相关(关联)的枚举示例,其中包含引用其他枚举的复杂类型字段。在这种情况下,枚举可以在数据不变时替换类。有没有客观的方法来看待这个问题。
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

虽然这个问题对于 Stack Overflow 来说可能太宽泛了,但有一些想法。

枚举

您可能没有完全理解 Java 中的枚举功能。请参阅Oracle 教程,并参阅Enum类文档。

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

  • 您的枚举可以携带成员变量。

  • 您的枚举可以有构造函数,并且您可以将参数传递给这些构造函数。

  • 您的枚举可以提供其他方法,并且您可以将参数传递给这些方法。

  • 您甚至可以将一个枚举的实例作为参数传递给另一个枚举实例的方法——就像您可以将一个枚举的实例传递给其他非枚举类的实例一样。每个枚举实例只是一个对象,简单明了,保存为枚举定义类上的静态引用。

例子:


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.

    }


}

枚举的限制

虽然比其他语言更强大和有用,但也有局限性。

编译时

首先,枚举是在编译时定义的。如果您的值在运行时更改,也许您想添加或删除项目,则枚举不合适。

永远留在记忆中

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

了解您可以收集枚举实例。有关枚举实例的快速执行和低内存使用情况集合,请参阅EnumSetEnumMap类。搜索 Stack Overflow 以获取有关此主题的大量报道。请注意,每个枚举都带有一个values()返回其值数组的方法,但是这个方法神秘地没有在 JavaDoc 中列出。

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

国际化

国际化和本地化似乎是一个正交的问题。您可以在枚举上添加一个方法来生成String其值的本地化表示。例如,请参阅DayOfWeek::getDisplayNameMonth::getDisplayName枚举方法。

数据库

如果您想在运行时动态定义您的值,或者您有无数个值,那么数据库是您的最佳选择。像Postgres这样严肃的数据库旨在管理内存、处理并发和高效执行。

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

递归层次关系

如果您试图表示任意深度层次结构的关系,那是另一个我不会在这里讨论的主题,只是说它通常是用递归实现的。搜索 Stack Overflow 和其他来源以了解更多信息。


查看完整回答
反对 回复 2021-07-14
?
偶然的你

TA贡献1841条经验 获得超3个赞

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


查看完整回答
反对 回复 2021-07-14
  • 2 回答
  • 0 关注
  • 267 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信