static initializers vs. cached values

H

HK

Every once in a while I find myself
writing static initializers for 'static final'
values. The initializers are non trivial, i.e.
they might even contain small loops.
Obviously this adds to the startup time of
a program.

Another solution would be getters
which compute the value on first use and
cache the result.

I am not worried really about the
startup time. It is rather that so many
things are done before the application's
main() even starts, some of them completely
unnecessary if the program does not
use a feature.

Any thoughts on this?
Harald.
 
T

Thomas Fritsch

HK said:
Every once in a while I find myself
writing static initializers for 'static final'
values. The initializers are non trivial, i.e.
they might even contain small loops.
Obviously this adds to the startup time of
a program.

Another solution would be getters
which compute the value on first use and
cache the result.
I would opt for your cached-value approach. Furthermore it has
the advantage that you can easily declare/throw exceptions
then, which would be a pain in the static-initializer approach.
private static Thing thing;
public static Thing getThing() throws AnyException {
if (thing == null)
thing = new Thing(); // heavy stuff here
return thing;
}
 
C

Chris Uppal

HK said:
I am not worried really about the
startup time. It is rather that so many
things are done before the application's
main() even starts, some of them completely
unnecessary if the program does not
use a feature.

One datum that might help: class intialisation doesn't happen until the class
is first referenced. E.g.

class AClass
{
private static int x = aVeryLongCalculation();

private int aVeryLongCalculation() { ... }
}

x will not be intialised, and hence aVeryLongCalculation() will not run, until
AClass is first used.

"used" in this context means:
- instance creation
- read or write of any static field
- call of any static method
there are also some obscure cases to do with using classes via reflection or
via JNI. As far as I can remember, these all "do the right thing" too.

Note: this lazy initialisation isn't an "optimisation" that a Java
implementation might, or might not, provide. The time at which class
initialisation happens is defined by the Java spec.

-- chris
 
H

HK

Chris said:
One datum that might help: class intialisation doesn't happen until the class
is first referenced. E.g.

Good hint as in most of my cases then I would
not gain anything by doing the lazy
evaluation myself.

Thanks,
Harald.
 
A

Adam Maass

Chris Uppal said:
One datum that might help: class intialisation doesn't happen until the
class
is first referenced. E.g.

class AClass
{
private static int x = aVeryLongCalculation();

private int aVeryLongCalculation() { ... }
}

x will not be intialised, and hence aVeryLongCalculation() will not run,
until
AClass is first used.

"used" in this context means:
- instance creation
- read or write of any static field
- call of any static method
there are also some obscure cases to do with using classes via reflection
or
via JNI. As far as I can remember, these all "do the right thing" too.

Note: this lazy initialisation isn't an "optimisation" that a Java
implementation might, or might not, provide. The time at which class
initialisation happens is defined by the Java spec.

Another note: though lazy, I find class initialization generally happens
much sooner than I expect. YMMV.

-- Adam Maass
 
W

Wibble

Thomas said:
I would opt for your cached-value approach. Furthermore it has
the advantage that you can easily declare/throw exceptions
then, which would be a pain in the static-initializer approach.
private static Thing thing;
public static Thing getThing() throws AnyException {
if (thing == null)
thing = new Thing(); // heavy stuff here
return thing;
}
Remember to synchronize the lazy accessor.

public synchronized static Thing getThing() throws AnyException {
 
W

Wibble

HK said:
Every once in a while I find myself
writing static initializers for 'static final'
values. The initializers are non trivial, i.e.
they might even contain small loops.
Obviously this adds to the startup time of
a program.

Another solution would be getters
which compute the value on first use and
cache the result.

I am not worried really about the
startup time. It is rather that so many
things are done before the application's
main() even starts, some of them completely
unnecessary if the program does not
use a feature.

Any thoughts on this?
Harald.

If your startup time isnt the issue, the following also works
in place of inline static initializers. Same thought but
easier to unitTest. This has simpler code then the lazy initializer
and doesnt require synchronized access to the singleton.

protected static Frob createSingleton() { /* complicated logic */ }
public final static Frob singleton = createSingleton();

Declaring lazy getters to avoid having them called before main, isnt
a guarantee either, since they can be called from other initializers.

Static initializers wont be invoked until the class is loaded.
Classes aren't loaded until they're referenced from other code.
You can use this to ensure classes arent loaded before main if
you care.
 
W

Wibble

HK said:
Every once in a while I find myself
writing static initializers for 'static final'
values. The initializers are non trivial, i.e.
they might even contain small loops.
Obviously this adds to the startup time of
a program.

Another solution would be getters
which compute the value on first use and
cache the result.

I am not worried really about the
startup time. It is rather that so many
things are done before the application's
main() even starts, some of them completely
unnecessary if the program does not
use a feature.

Any thoughts on this?
Harald.

If the features are unnecessary, delete them.

Also, dont use lazy initialization if the initialization is cheap.
Its added complexity, and wont save memory by avoiding allocation,
since it has to use memory to add the extra code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top