Purpose of static member fields in a class
Hi,
I hope that subject makes sense, because I don't know how to describe this clearly (otherwise I'd just Google it).
Occasionally, I've come across some code that says something like:
publicfinalclass MyClass{
private String s;
static{
s ="blah";
System.out.println(s);
}
}
What is the purpose of that static {} declaration? I know it will always execute when the class is instantiated, but why not just put something like the above code in the constructor?
Unfortunately, I do not have JDK installed on this machine, or I would test out these next questions myself, but they are just yes/no questions, so hopefully they can be answered easily.
Does the static {} declaration execute when a Class' static method is called (i.e. I do not instantiate the class)? If so, why not just put the code inside static {} inside a method?
Does the static {} declaration get executed before the constructor code? I'm pretty sure that the constructor is always the first thing that executes when a Class is instantiated. Is this incorrect?
Basically, my question is: what is the point of using a static {} declaration in the class?
Thanks,
Dan
[1540 byte] By [
Djaunla] at [2007-11-27 10:18:13]

I never really use them and wondered really what their use was. In a static block you can use logic that you can't use in a typical variable initialization.
There is a good example in Effective Java. Here is an example from the book.
It points out that the this helps with performance when isBabyBloomer method is being called often(and a new Calendar is being created each time)
//The bad way to do this:
public class Person {
private final Date birthDate;
// Other fields omitted
public Person(Date birthDate) {
this.birthDate = birthDate;
}
public boolean isBabyBoomer() {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
//The correct way
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
The method is now a lot easier to read (which has nothing to do with static I know) and the performance is better too.
Still, I never really use em myself.
> is it just for readability purposes?
No. The *static* initializer is run once, while code in a constructor could be run many times. In the example, we only need to calculate BOOM_START and BOOM_END once.
Only the other hand, Java syntax also includes instance initializers:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6
public class X {
{
//instance initializer -- note no "static"
}
}
I find I hardly use them, but I can think of a couple specific pluses:
1. Anonymous classes - you can't write a constructor but you can write
an instance initializer:
Runnable r = new Runnable(){
{
//do some init here
}
public void run() {...}
};
2. How do you guarantee every constructor executes a block of code?
You could put it in an "init" method and try to remember to call it from
each constructor, or put it in one constructor and try to remember to
use this(args...), or you could use a initializer block.
3. Tools: some code generation tools may find it easier to generate
initializer blocks that to monkey with constructors, especially if the
code is allowed to be amended by humans/other tools later.