views:

239

answers:

6

I know how a static init block works.
Can anyone please tell me some typical uses of it.

+4  A: 

Just try to avoid use of static initialization block. Instead you can use private static initialization functions which will make your code more clean.

I will refer @Bozho examples.

Do not

public static Configuration configuration;
static {
     confuguration = new Configuration();
     configuration.setSomething(..);
     configuration.setSomethingElse(..);
     ...
}

Use

public static Configuration configuration = createConfiguration();

or

public static Configuration configuration = YourConfiguration.create();
Mykola Golubyev
quite correct..
Bozho
Agreed. Use a block as stated above creates serious issues with unit testing.
gpampara
any static resource creates an issue with unit-testing :)
Bozho
No. If you use Groovy for unit testing.
Mykola Golubyev
+5  A: 

When you want to initialize one or more static variables in one place

It is useful, because you can apply exception handling, which is not possible with the in-line initialization.

For example:

public static ImageIcon defaultIcon = ImageIO.read(..);

can be initialized with

public static ImageIcon defaultIcon;
static {
   try {
       defaultIcon = ImageIO.read(..);
   } catch (IOException ex){
     System.out.println("No default icon available");
   }
}

Another application is complex initialization. For example, if an item requires more than one line of code to be initialized. Let's say you have a configuration:

public static Configuration configuration;
static {
     confuguration = new Configuration();
     configuration.setSomething(..);
     configuration.setSomethingElse(..);
     ...
}

A third usage is to initialize some external API infrastructure. One example from my current project:

static {
    org.apache.xml.security.Init.init();
}

But, as Mykola Golubyev noted, static initialization blocks make code less readable, so use them with caution. static methods do the same thing more transparently.

Bozho
If which class do you use your example with "security.Init.init()"?
Mykola Golubyev
It is required by the API. See http://santuario.apache.org/Java/api/org/apache/xml/security/Init.html
Bozho
+2  A: 
  • Initializing a collection static field, like Map, List, Set, etc
  • Initializing setter-based object which is also static
nanda
+2  A: 

They're often used in conjunction with JNI code to ensure that the required native library is loaded:

class MyJniConnection {

    public static native void myJniCall();

    static {
        System.load("native.dll");
    }
}
Joonas Pulakka
+1  A: 

They can be used to create a DSL, as JMock does. For instance, to set an expectation that a user will be saved to the database:

Mockery context = new Mockery();
final Database database = context.mock(Database.class);    
...
context.checking(new Expectations() {{
    oneOf(database).save(user);
}});

// Rest of the test
Michael Williamson
+1  A: 

JDBC Driver Is a Popular Example

Why do you need Class.forName() to load a driver into memory. The answer is simple. As stipulated in the JDBC specs, all JDBC Driver have a static block to register themselves with DriverManager as soon as the Driver class is loaded. Something like this:

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

So, when you write (for example with the MySQL driver here):

Class.forName("org.gjt.mm.mysql.Driver");

The classloader attempts to load and link the org.gjt.mm.mysql.Driver class and, if successful, the static initialization block gets executed and the Driver registers itself with the DriverManager.

Pascal Thivent