String constants usually live as long as the code using it is alive. While in theory, String constants not being referred by variables could be freed and recreated on their next use, this doesn’t happen with current JVMs.
Still, there is a small overhead regarding the fields holding the references, not only the size of an object reference, but also the associated metadata, that you could avoid. Just place the constants in a dedicated holder class:
public class Singleton {
private static final class Constants {
static final String CONSTANT_1 = "Foo";
static final String CONSTANT_2 = "Bar";
static final String CONSTANT_3 = "Baz";
static final String CONSTANT_4 = "etc";
private Constants() { throw new AssertionError(); }
}
// …
// Use the constants either via Constants.CONSTANT_1, etc.
// or using import static Singleton.Constants.*; and
// unqualified names ala CONSTANT_1, CONSTANT_2, etc.
// …
}
That class doesn’t need to be a nested class, but Constants
is designed as nested class to be private
to Singleton
as intended. Since we’re talking about constants, their use does not imply a field access, instead, the constant value will be used. In other words, since the nested class Constants
is never actually used at runtime, it will never get loaded, hence, the fields do not occupy memory, neither in the heap nor in the metaspace.
So what’s remaining, is the code actually referring to the constant values. As said, there is even the theoretical possibility of collecting the string instances, if the code doesn’t run for a longer time (as long as no other code nor variables refer to the same constant), but this possibility is not used by current JVMs. Collecting the String instance while the code is reachable would also imply the necessity to have the original content, e.g. in class file form, still at hand.
It should be emphasized that the code referring to the constants will be identical, regardless of whether the constants are final
variables, like static
or instance fields in Singleton
, static
fields in another holder class, or even local variables. These variants only differ in whether or what kind of additional variables exist, referring to the same constants.