Reputation: 451
For a Singleton class, is it a good idea to keep String constants (used internally in the member functions) as private static final
or private final
?
I want to know more in terms of difference in class's memory footprint for a long running application and otherwise.
Note : I know how static
and final
affect a variable. My question is specific to Constants that are used as private
to the class. More specifically - about there lifetime. Even when there is no object of that class lying in memory.
Upvotes: 2
Views: 7026
Reputation: 298469
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.
Upvotes: 2
Reputation: 118
There is not much difference between those, only that the private static final String
gets initialized when the program gets initialized, the private final String
gets initialized when the Singletons instance is being created.
The only advantage of the static
String is, is that you can use it in static methods too (if you need them)
Also there are no performance issues with both of them, as both variables won't get garbage collected as long as the program is running.
Upvotes: 1