4

I am trying to run this code, I but found out this behavior of final with static: the code runs without executing static block of A. Please provide me with the reason.

class A {
  final static int a=9;
    static { //this block is not executing ??
      System.out.println("static block of A");
     }
}

class Manager {
  static {
    System.out.println("manager sib");
  }

  public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(A.a);
  }
}

Why doesn't the static block of Class A run?

1
  • 1
    Please fix the indentation of the code in your questoin. Currently it's unreadable. Commented Mar 19, 2013 at 20:05

3 Answers 3

7

The problem is that A.a is a constant variable.

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

Therefore your Manager.main method is compiled exactly as if it were:

public static void main(String ...arg) {
    System.out.println("main");
    System.out.println(9);
}

There's no real reference to A.a any more, so the A class doesn't even need to exist, let alone be initialized. (You can delete A.class and still run Manager.)

If you're relying on using A.a to make sure the type is initialized, you shouldn't add a no-op method instead:

public static void ensureClassIsInitialized() {
} 

then just call that from your main method. It's very unusual to need to do this though.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks i was not doing it in my program but it was asked to me in an interview why static block of A will not run...
Yeah ,But if Final would have not been there with int a=9 then static would have worked why its not executing with final...pls help me out!!
@Sandepp1: Without final, it wouldn't be a compile-time constant expression.
1

Specification http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf Section 4.12.1 Says,

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).

As you are only accessing the constant, class initialization is not required.

Comments

0

You can force-load whatever class you need:

public final class ClassUtils {
  private ClassUtils() {}

  public static void forceLoad(Class<?>... classes) {
    for (Class<?> clazz : classes) {
      try {
        Class.forName(clazz.getName(), true, clazz.getClassLoader());
      } catch (ClassNotFoundException e) {
        throw new AssertionError(clazz.getName(), e);
      }
    }
  }
}

class Manager {
  static {
    ClassUtils.forceLoad(A.class);
// ...
  }

  public static void main(String ...arg) {
// ...
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.