public class StaticTest { private int i; public static void main(String[] args) { //i = 1; //Compile error, cannot reference non-static variable } }Obviously there is a compile error, static methods cannot reference non-static variables.
Static resources belong to classes, but exist independently of classes. From the perspective of the JVM's class loading mechanism, static resources are loaded when the class is initialized, while non-static resources are loaded when the class is new . The initialization of a class is earlier than the new of the class, such as the Class.forName("xxx") method, which initializes a class, but does not new it, just loads the static resources of this class. So for static resources, it is impossible to know which non-static resources are in a class; but it is different for non-static resources, because it is generated after new, so these things belonging to the class are can all know. So the answers to the above questions are clear:
1. Can static methods reference non-static resources? No, things that are only generated when new are not recognized at all for static resources that exist after initialization.
2. Can static resources be referenced in static methods? Yes, because they are loaded when the class is initialized, and everyone knows each other.
3. Can static resources be referenced in non-static methods? Yes, a non-static method is an instance method, which is generated after new, so it knows all the content belonging to the class.
public class A { private static int a = B(); static { System.out.println("Enter A.static block"); } public static void main(String[] args) { new A(); } public static int B() { System.out.println("Enter A.B()"); return 1; } }The result of running this code is:
Enter A.B() Enter A.static blockThe first conclusion is drawn from this: the loading order of static resources is strictly in accordance with the definition order of static resources . This is similar to what Mr. Zhou Zhiming said in class initialization in "In-depth Understanding of Java Virtual Machine: Advanced Features and Best Practices of JVM" "The <clinit>() method is to automatically collect assignment actions and static statement blocks of all class variables in the class by the compiler. (static{} block), the order in which the compiler collects is determined by the order in which the statements appear in the source file " is consistent.
public class A { static { c = 3; //System.out.println(c); //Compile error, cannot be used, undefined } private static int c; }A second conclusion is drawn from this example: a static code block can assign values to static variables defined after it, but cannot access them . PS: Generally, we don't write code like this.
public class A { static { System.out.println("A.static block"); } public A() { System.out.println("A.constructor()"); } }
public class B extends A { static { System.out.println("B.static block"); } public B() { System.out.println("B.constructor()"); } public static void main(String[] args) { new B(); new B(); } }Execute this code and the output is:
A.static block B.static block A.constructor() B.constructor() A.constructor() B.constructor()This is easy to understand, and this example draws the third conclusion: static code blocks are loaded strictly in the order of parent class static code block -> child class static code block, and only loaded once .