32

Who can explain what's going on?

public class MagicFinal {

    public static void main(String[] args) {
        System.out.println(A.s);
    }
}

class A {
    static {
        System.out.println("class has been loaded");
    }

    public static final String s = "final";

    public static final Integer i = 3;
    
        
}

Console :

final

What's it? I don't understand why the class has not been loaded, I know classes always load at the first call. Field s is in pool of string, I see that final modifier is magic.

If I delete final modifier (public static String s = "final" ) I will get

Console :

class has been loaded

final

Note: I have changed field i : public static final int i = 3; and show it in console. I got the same as in String situation. Why?

4

2 回答 2

46

"final" is a string literal and as such is a compile-time constant expression. The value of a static final variable initialized with a compile-time constant expression is directly hardcoded into the class which references it, and no reference is made to the originating class. Therefore the initialization of the originating class does not occur.

As a side point, please note the distinction between class loading and class initialization: only the latter's occurrence is precisely specified by the JLS. Class loading can happen at any time.

于 2013-09-24T10:34:15.913 回答
3

This is what is written in Java Language Specification {8.3.2.1 Initializers for Class Variables}. This must answer your question

One subtlety here is that, at run time, static variables that are final and that are initialized with compile-time constant values are initialized first. This also applies to such fields in interfaces (§9.3.1). These variables are “constants” that will never be observed to have their default initial values (§4.12.5), even by devious programs. See §12.4.2 and §13.4.9 for more discussion.

于 2013-09-24T10:57:18.987 回答