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]
# 1

> Basically, my question is: what is the point of using a static {} declaration in the class?

Static initializer blocks are executed when the class is loaded. The Point?

I don't use them often, but I've found then handy to initialize static fields that

require a chunk of code for initialization.

BigDaddyLoveHandlesa at 2007-7-28 15:56:12 > top of Java-index,Java Essentials,Java Programming...
# 2

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.

_helloWorld_a at 2007-7-28 15:56:12 > top of Java-index,Java Essentials,Java Programming...
# 3

Thanks for the replies; they make sense to me.

I understand the purpose of the "good" example from helloWorld's post. One thing I'm still wondering however, is why that static initialization cannot be done in the class constructor in the above case. I understand why that is impractical if you're only calling a class' static methods, but if you're instantiating a class, it seems like that code can just be in the constructor.

Is it just for readability purposes?

Thanks

Djaunla at 2007-7-28 15:56:12 > top of Java-index,Java Essentials,Java Programming...
# 4

> 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.

BigDaddyLoveHandlesa at 2007-7-28 15:56:12 > top of Java-index,Java Essentials,Java Programming...
# 5

Ah alright, I understand their purpose now. In fact, I can actually think of a use for this in one of my applications.

Thanks for the help.

Djaunla at 2007-7-28 15:56:12 > top of Java-index,Java Essentials,Java Programming...