1

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.

  • IMHO one should not use singletons in the first place; they get in the way of unit testing and are just messy to deal with. So I'd make the field non-static, so that the class can be relieved of its singleton status easily. I don't know what that field is, but being concerned about performance and memory management here is probably premature optimization, which is a really bad idea, even worse than singletons. – Robert Jul 23 '23 at 17:53
  • There are [different ways](https://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) of implementing a singleton in Java - you have to be specific which implementation you're discussing. – Nir Alfasi Jul 23 '23 at 17:53
  • @NirAlfasi thank you for your feedback, I have added the relevant information. – Luca Blanchi Jul 23 '23 at 18:39
  • This is a "what is your opinion" kind of question - there isn't a "best practice. – Nir Alfasi Jul 23 '23 at 20:59
  • A static context would be irrelevant if the class is a singleton. – Reilas Jul 23 '23 at 21:58
  • Constants should always be static, regardless of singletons. There is no reason to instantiate them per object instance. – user207421 Jul 24 '23 at 01:03

1 Answers1

0

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.

Andreas Lundgren
  • 12,043
  • 3
  • 22
  • 44
  • Note that the objects (assuming it is not a primitive and not a `String` though ot probably holds for the latter as well) will always be stored on the heap - just the reference mad be stored differently. Aside from that, inlining of constants happens with `static final` primitives/strings _iff_ they are not not obtained using only arithmetic operations/string concatenation and other `static final` variables (Also I like the GIT compiler typo:)) – dan1st Jul 23 '23 at 21:38