I am very good for beginner java, this article is very good! Introduction Java initialization
About Java initialization, there are many articles to introduce a lot. Classic << Thinking in Java >> is a special chapter to introduce Java initialization. However, after a large number of code instances, it feels still not really deep into the nature of the initialization.
This paper uses the author's understanding of JVM and its own experience, and the initialization of Java is more than in-depth, due to the level of the author, and the change of the JDK implementation, there may still be many errors and disadvantages. Welcome expert masters to enlighten me.
To learn from Java initialization, we can't know what JVM is executed from the program process. Understanding the implementation mechanism and stack tracking of JVM is a means of effective means. It is a pity that so far. JDK1.4 and JDK1.5 still have bugs on JavaP. So some processes I can't use the actual results to prove the two opposite situations (but I can prove that is indeed a bug)
<< Thinking in Java >> (Thin 3) At the beginning of Chapter 4, this will describe the initialization of Java: The following translation: Can thus think that each class has a method called initialize () This name suggests that it is called before use. Unfortunately, if this is done, the user has to remember that the method to call this method, the designers of the Java class library can pass a special approach called constructor. To ensure that each object can be started. If the class has a constructor, Java will automatically call the constructor when the object is just created, the user is still not too late, so that initialization is guaranteed.
I don't know how much difference between the description of the original author and the translator's understanding, combined with the whole chapter, I didn't find two most critical words "
Where is "
Now there is a strange phenomenon in the scientific system. The huge system is originally based on a hypothesis. It is assumed that 1 is correct, thereby derived 2, and then continue to derive 10000000000. It is a pity that too many people don't care about 2-100000000,000. It is based on the assumption 1 is based on the right basis. I will not use "I can think so" this assumption, I have to prove that "
Package debug; public class mytest {static int i = 100/0; public static void main (string [] args) {ssytem.out.println ("Hello, World!");}}
Execute a look, this is the output of JDK1.5:
Java.lang.ExceptioninInitializerrrorcaused by: java.lang.Aithmeticexception: / by zero at debug.mytest.
Note that the exception generated during the call is called, the abnormality is positioned in the debug.mytest's
Let's see again:
Package Debug; public class test {test () {INT i = 100/0;} public static void main (string [] args) {new test ();}}
JDK1.5 Enter: Exception in Thread "Main" java.lang.arithmeticexception: / by zero at debug.test.
JVM does not position an exception in a Test () constructor, but in debug.test.
When we see these two methods, we will discuss these two "built-in initialization methods" in detail (I don't like to create some non-standard terms, but I really don't know how to standardize them).
The built-in initialization method is a unique way to specifically for initialization internally, rather than providing the programmer calling, in fact, "<>" syntax in the source program cannot be passed in the source program. This shows that initialization is controlled by JVM instead of letting programmers.
Class initialization method:
When the class is loaded (LOAD), the JVM calls the built-in
Compiled from "Test.java" public class debug.test extends java.lang.object {static int x;
Static java.lang.string s;
Public debug.test (); Code: 0: ALOAD_0 1: InvokeSpecial # 1; // method java / lang / object. "
Public static void main (java.lang.string []); code: 0: New # 2; // Class Debug / test 3: DUP 4: InvokeSpecial # 3; // method "
Static {}; code: 0: iconst_0 1: PutStatic # 4; // Field x: i 4: LDC # 5; // String 123 6: PutStatic # 6; // Field S: Ljava / Lang / String; 9: LDC # 7; // String 456 11: ASTORE_0 12: New # 8; // Class Java / Lang / RuntimeException 15: DUP 16: InvokeSpecial # 9; // Method Java / Lang / RuntimeException. "
Java.lang.ExceptioninInitializerrrorcaused by: java.lang.RuntimeException at debug.test.
But we can always understand that class initialization is in accordance with the order sequence defined in source files. First declaration
Static int x;
Static java.lang.string s;
Then assign INT X and String S: 0: iconst_0 1: PutStatic # 4; // Field x: i 4: LDC # 5; // String 123 6: PutStatic # 6; // Field S: Ljava / Lang / String; String S1 = "456" to perform the initialization block; generate a RuntimeException 9: LDC # 7; // String 456 11: ASTORE_0 12: New # 8; // Class Java / Lang / RuntimeException 15: DUP 16: InvokeSpecial # 9; // Method Java / Lang / RuntimeException. "
It should be understood that "
[public static final] Double D = Math.random () * 100;
Such an expression is to be calculated, and in the interface is initialized by the
Let's take a look at the instance initialization method "
"
Similarly, the order in which the instance variable and the initialization block is also executed in the original order of the source file, the code in the constructor is executed at the last execution: package debug; public class test {int x = 0; string s = "123"; {String S1 = "456"; // IF (1 == 1) // throw new runtimeException ();}
Public test () {string ss = "789";
Public static void main (string [] args) {new test ();}}
Javap -c debug.test results:
Compiled from "Test.java" public class debug.test extends java.lang.object {int x;
Java.lang.string s;
Public debug.test (); code: 0: ALOAD_0 1: InvokeSpecial # 1; // method java / lang / object. "
Public static void main (java.lang.string []); code: 0: New # 7; // Class Debug / test 3: DUP 4: InvokeSpecial # 8; //Method "
If in the same class, a constructor calls another constructor, then the corresponding "
Package debug; public class test {string S1 = r ("s1"); string S2 = "s2"; public test () {S1 = "S1";} public test (string s) {this (); if (1 == 1) throw new runtime (); String RT (String s) {returnit s;} public static void main (string [] args) {new test ("");}}
Reflexible results: Compiled from "test.java" public class debug.test extends java.lang.object {java.lang.string s1;
Java.lang.string s2;
Public debug.test (); code: 0: ALOAD_0 1: InvokeSpecial # 1; // method java / lang / object. "
Java.lang.String RT (java.lang.string); Code: 0: ALOAD_1 1: ARETURN
Public static void main (java.lang.string []); code: 0: New # 10; // Class Debug / test 3: DUP 4: LDC # 11; // String 6: InvokeSpecial # 12; //method
}
We once again saw the javap-implemented bug, although there is a "
But we see that Test () is called due to TEST (String S); so "
Public debug.test (java.lang.string); code: 0: ALOAD_0 1: InvokeSpecial # 7; // method "
Package debug; public class test {string S1 = r ("s1"); string S2 = "s2"; {String S3 = "s3";} public test () {S1 = "s1";}
Public test (string s) {if (1 == 1) throw new runtimeException ();
String RT (String s) {Return S;}
Public static void main (string [] args) {new test ("");}}
Reflexible results:
Compiled from "Test.java" public class debug.test extends java.lang.object {java.lang.string s1;
Java.lang.string s2;
Public debug.test (); code: 0: ALOAD_0 1: InvokeSpecial # 1; // method java / lang / object. "
Public debug.test (java.lang.string); Code: 0: ALOAD_0 1: InvokeSpecial # 1; // Method Java / Lang / Object. "
Public static void main (java.lang.string []); code: 0: New # 10; // Class Debug / test 3: DUP 4: LDC # 11; // String 6: InvokeSpecial # 12; //method
}
Tired, write here first.