How to force a class to be initialised?

JavaCoding StyleStatic Initializer

Java Problem Overview


What is the best and cleanest way to do this? Specifically, I need some code in a static initializer block to run in that class, but I'd like to make this as clean-looking as possible.

Java Solutions


Solution 1 - Java

Loading != Initialization.

You want your class to be initialized (this is when static blocks executed, among other things).

An excerpt from the Java Language Specification says:

>A class or interface type T will be initialized immediately before the first occurrence of >any one of the following: > > * T is a class and an instance of T is created. > * T is a class and a static method declared by T is invoked. > * A static field declared by T is assigned. > * A static field declared by T is used and the field is not a constant variable (§4.12.4). > * T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed. > >Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.

Doh, anovstrup, already said it: Just make an empty static function called init. Be sure to document that well... I personally can't see any use case for this in the context of well formed code though.

Solution 2 - Java

You can use the following code to force initialization of a class:

//... Foo.class ...          //OLD CODE
... forceInit(Foo.class) ... //NEW CODE
    
/**
 * Forces the initialization of the class pertaining to 
 * the specified <tt>Class</tt> object. 
 * This method does nothing if the class is already
 * initialized prior to invocation.
 *
 * @param klass the class for which to force initialization
 * @return <tt>klass</tt>

 */
public static <T> Class<T> forceInit(Class<T> klass) {
    try {
        Class.forName(klass.getName(), true, klass.getClassLoader());
    } catch (ClassNotFoundException e) {
        throw new AssertionError(e);  // Can't happen
    }
    return klass;
} 

Solution 3 - Java

try
{
  Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
  whatever
}

That should do it.

@Longpoke

Maybe I am misunderstanding something then. Can you create an example where a class is loaded but the static initializer is not executed? Here is an example that does nothing but print out that it has loaded:

package test;

public class TestStatic 
{
	public static void main(String[] args) 
	{
		try 
		{
			Class.forName("test.Static");
		}
		catch (ClassNotFoundException e) 
		{
			e.printStackTrace();
		}
	}
}

With the following Static class being loaded:

package test;

public class Static 
{
	static
	{
		System.out.println("Static Initializer ran...");
	}
}

If the static initializers are not ran until the conditions you listed are met then why does this println get executed when I run my test? That is which of your listed conditions am I meeting?

Solution 4 - Java

Invisible dependencies between classes is not a good idea. I suggest moving the code in static initializer block to a static method and calling it directly in the dependent class. The static initializer block can be rewritten to call the newly created static method.

Solution 5 - Java

One solution would be to call a static method:

public class A {
   static { DebugUtils.FLAG_TEST_USER = true; }

   static void init() {}
}

Then invoke A.init() to force initialization.

However, doing this at all is a code smell. Consider replacing your static code with a standard constructor in a singleton object.

Solution 6 - Java

If you need to statically initilize something in a Class that means there must be client classes dependent on that.

If there is one client, or let's call it a natural home for the initializing block, I think it would be cleanest to initialize it there.

For the many equal clients case, it may be a good idea to verify from these classes that the static initalization in the other class was successful. Then the coupling is documented and you are sure the class is always initialized before the first client needs it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArtemView Question on Stackoverflow
Solution 1 - JavaL̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳View Answer on Stackoverflow
Solution 2 - JavaIulianView Answer on Stackoverflow
Solution 3 - JavaBigMac66View Answer on Stackoverflow
Solution 4 - JavaAbhinav SarkarView Answer on Stackoverflow
Solution 5 - JavaAaron NovstrupView Answer on Stackoverflow
Solution 6 - JavaPeter TillemansView Answer on Stackoverflow