9
public class A {
  public static String HOST;

  static {
    HOST = ...;
  }
}

public class B {
    public static String URL;

    static{
         URL = A.HOST + ...;
    }
}

My question is if A.HOST would be correctly initialised before B use it? Is this behaviour is defined in spec?

3
  • just run a simple test to see if it gets initialized or not Commented Jul 15, 2015 at 11:11
  • if you make any reference to A first, A will be fully initialized, and whenever you call B for the first time, it will work fine. If you call B first, it will cascade to A when encountering A.HOST. Commented Jul 16, 2015 at 18:18
  • the funny part would be if A had something like HOST = B.FOO. Not sure that one would even compile, though. Commented Jul 16, 2015 at 18:19

5 Answers 5

9

Yes that behavior is well defined here.

In short, citing from that link

Initialization of a class or interface consists of executing the class or interface initialization method <clinit>

...

A class or interface may be initialized only as a result of:

The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references the class or interface (§new, §getstatic, §putstatic, §invokestatic). All of these instructions reference a class directly or indirectly through either a field reference or a method reference.

Upon execution of a new instruction, the referenced class or interface is initialized if it has not been initialized already.

Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.

The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic).

Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.

The initialization of one of its subclasses.

Its designation as the initial class at Java Virtual Machine start-up (§5.2).

The <clinit> method is the method (created by the compiler) that initializes static variables and has the code that you put in the static block

In your case, when the static block of class B runs (which is what <clinit> will do), it will have a getStatic opcode, requesting A.HOST. So the initialization of A will be triggered, and A.HOST initialized. So you will read the proper value.

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

2 Comments

And your conclusion is yes or no, A will be initialized before B uses it ?
@user3360241 Just edited, let me know if it's still not clear.
0

The static block for a class gets executed when the class is accessed, either to create an instance, or to access a static method or field.

This depends on the code that we are executing.

In your case, when we do A.HOST, it calls static block of class A also.

Refer this

Comments

0

The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field.

Source: In what order do static initializer blocks in Java run?

Comments

0

I came across your post since I have similar doubt.

When there is a cycle dependency, it does looks like it is problematic in some cases. Here is my test code.

The output from https://www.tutorialspoint.com/online_java_compiler.php for below is ABC_null_TT2_EFG

 class A {
    public static String HOST;

    static {
        HOST = "ABC_" + B.TT + "_" + B.TT2;
    }
    
}

public class B {
    
    public static String URL;

    static {
        URL = A.HOST + "_EFG";
    }
    public static void main(String[] args) {
        System.out.println(URL);
    }
    public static String TT = "TT";
    public final static String TT2 = "TT2";
}

1 Comment

That's not caused by a cyclic dependency, but because non-final static intialisers are execute in order -- try moving the assignment to TT to before the initialiser block.
-3

A static block will be executed,before the main() method executes.

4 Comments

could you explain how your answer is related to the question asked?
I mean code in the static block executes prior to main method, class B is written next to class A,probably string get initialized and there would be no problem when it is accessed by class B.
I think you did not understand the question. B.URL and A.HOST are both static. But B.URL initialisation requires A.HOST. So the problem is as A has not yet been initialised when B.URL is being initialised, will it cause any problem or not?
I just confused with program flow,yes it is a problem.Thanks for your comment.

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.