在Java中,应该将单例中的常量设置为静态吗?

huangapple go评论65阅读模式
英文:

Should one make constants in singletons static in java?

问题

一个单例类中的最终字段应该是常量的(假设是不可变的),无论它是否是静态的,因为该类不能持有不同值的多个实例。

是否仍然要将字段声明为静态,或者不这样做是否有原因?

将其声明为静态的一个原因是明确表示意图。但是否有关于内存管理的微妙之处可能使一个做法更佳?

据我理解,不是静态情况下,分配给字段的对象的引用存储在堆空间中的类实例中,而在静态情况下,它存储在元空间中,但我不知道哪一个(如果有的话)更受青睐。

编辑:有用户指出单例的实现可能会有所不同。这个问题涉及到Spring组件,手动创建多个实例是可能的,但实际上不会发生。

英文:

A final field in a singleton class should be constant (assuming immutability) regardless of whether it is static, as there cannot be multiple instances of the class holding different values.

Are there reasons to still declare the field as static, or not to do so?

One reason to make it static is clear declaration of intent. But are there nuances regarding memory management that could make one practice best?

To my understanding, what differs is that in the non-static case, the reference to the object assigned to the field is stored in the class instance in heap space, while in the static case it's stored in metaspace, but I don't know which one (if any) is to be preferred.

Edit: A user noted that the implementation of the singleton may make a difference. This question came up regarding Spring components, where manually creating multiple instances could be done, but will not happen in practice.

答案1

得分: 0

我会说你已经对答案有了了解,这涉及到堆和元空间。对于非静态版本,数据需要同时存在于两者中,它需要一直存在于元空间,并在实例化后复制到对象的(单例)实例中。

如果数据很小,比如一个单一的原始值,如果声明为静态常量,它可以直接存储在指令内存中,而且在执行期间可能会在一个时钟周期内访问。但谁知道,也许GIT编译器无论如何都能实现这一点。 🤷

如果是一个大型数据集,声明为静态常量可以避免数据复制(或者如果使用序列化或反射覆盖了单例意图,则可能会有更多复制),因为只需要元空间中的版本。

所以我会说没有理由不将其声明为静态常量。这可能不会造成任何损害。省下的一字是一字赚。 😄

英文:

I would say that you are on to the answer already, it's heap vs meta space. For the non-static version, the data needs to be in both, it needs to be in metaspace all the time, and copied over to the (singelton) instance of the object once it's instantiated.

If it's small data, like a single primitive value, it can be stored directly in the instruction memory itself if declared static final, and are then likely to be accessed within a single clock cycle during execution. But who knows, maybe the GIT compiler can achieve this anyway. 🤷

If it is a lagre dataset, declaring it static final avoid a data copy (or more if the singelton intention is overridden using serialization or reflection) since only the version in metaspace is needed.

So I would say no reason to not have it declared static final. It will probably not do any harm. A byte saved is a byte earned. 😄

huangapple
  • 本文由 发表于 2023年7月24日 00:53:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76749378.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定