Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What really happens when loading a class in java?

Tags:

java

I'm confused with the process of loading a class. What is the order in which members of a class are executed?

See the following:

class L {

    static void fr(){
        a=1;
        b=3;
        a=b;
    }

    static{
        a=3;
        b=1;
        a=b;// here the problem:cannot reference a field before it is defined
    }

    static int a;
    static int b;

    public static void main(String args[]) {

    }
}

Whenever I move the declarations of a and b to the top before the static block, compilation works fine. So I need to understand how this stuff works to resolve the problem above.

like image 308
user3478590 Avatar asked Sep 30 '22 17:09

user3478590


1 Answers

In Java, it is illegal to refer to a class variable before it is declared, if it's not an expression initializing it. Java will execute initializers in a class in textual order.

Section 12.4.2 of the JLS states:

Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

Section 8.3.3 of the JLS states:

Use of class variables whose declarations appear textually after the use is sometimes restricted, even though these class variables are in scope (§6.3). Specifically, it is a compile-time error if all of the following are true:

  • The declaration of a class variable in a class or interface C appears textually after a use of the class variable;

  • The use is a simple name in either a class variable initializer of C or a static initializer of C;

  • The use is not on the left hand side of an assignment;

  • C is the innermost class or interface enclosing the use.

All of these are true. The declaration appears after the use in a=b;. It's in a static initializer. It's not on the left side of an assignment, and it's the innermost (only) class.

The simplest way to get this to compile is to move the declarations above the static initializer in the source code.

Interestingly, replacing a=b; with a=L.b; will also get this to compile, because the reference to b is no longer "simple".

like image 66
rgettman Avatar answered Oct 11 '22 00:10

rgettman