Initialization in Java --- Select Blog from Axman

xiaoxiao2021-03-06  96

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 "" and "". At least indicated that the original author and the translator did not really show what JVM did, or did not understand the initialization of JVM, or it would be clearly there is two ways, but why do you think there is something that does not exist? "What is the INITIALIZE ()" method?

Where is "" and "" method? These two methods are actually existed and the way you can't find, maybe just this make some masters. Plus some bugs in JDK implementation, if there is no in-depth understanding, it is really not able to touch the north.

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 "" and "" method is true:

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. (Test.java: 3) Exception in thread "main"

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. (Test.java: 4) at debug.test.main (Test.java: 7)

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: I have not learned from anywhere to the CLASS short, but this method is indeed used to initialize "class". In other words, it is used to initialize the Static context.

When the class is loaded (LOAD), the JVM calls the built-in method to initialize the class member and the static initialization block. Their order is in the original order of the source file. We slightly add two lines static statement: package debug; public class test {static int x = 0; static string s = "123"; static {string S1 = "456"; if (1 == 1) throw new runtimeException () } Public static void main (string [] args) {new test ();}} then anti-compilation: javap -c debug.test

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. "" :() V 4: Return

Public static void main (java.lang.string []); code: 0: New # 2; // Class Debug / test 3: DUP 4: InvokeSpecial # 3; // method "" :() v 7 : POP 8: Return

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. "" :( , Here, we have to say that the JDK has a bug in JavaP functionality. The 16-labeled STATIC segment, which identifies the abnormal position in the "" method, and the output of this program is:

Java.lang.ExceptioninInitializerrrorcaused by: java.lang.RuntimeException at debug.test. (Test.java: 8) Exception in thread "main"

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. "" :() V 19: Athrow

It should be understood that "" method is not only a class initialization method, but also the interface initialization method. Not, the properties of the interface are inline, and only the interface constant of the direct value is inline. and

[public static final] Double D = Math.random () * 100;

Such an expression is to be calculated, and in the interface is initialized by the method.

Let's take a look at the instance initialization method ""

"" is used to initialize the object when the object is created. When the object is created in the HEAP, the space is assigned in HEAP. The "" method will be called first. This method includes the assignment of instance variables (declared) and initialization blocks, and constructor calls. If there are multiple overloaded construction methods, each constructor has a corresponding "" 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. "": () V 4: ALOAD_0 5: ICONST_0 6: Putfield # 2; // FIELD X: I 9: ALOAD_0 10: LDC # 3; // String 123 12: Putfield # 4; // Field S: Ljava / Lang / String; 15: LDC # 5; // String 456 17: ASTORE_1 18: LDC # 6; // String 789 20: ASTORE_1 21: Return

Public static void main (java.lang.string []); code: 0: New # 7; // Class Debug / test 3: DUP 4: InvokeSpecial # 8; //Method "" :() v 7 : POP 8: Return}

If in the same class, a constructor calls another constructor, then the corresponding "" method calls another "", but the instance variable and the initialization block will be ignored, otherwise they will Will be executed multiple times.

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. "":: () V 4: ALOAD_0 5: ALOAD_0 6: LDC # 2; ////// String S1 8: Invokevirtual # 3; // Method RT: (Ljava / Lang / String;) Ljava / Lang / String; 11: Putfield # 4; // Field S1: Ljava / Lang / String; 14: ALOAD_0 15: LDC # 5; // string S2 17: Putfield # 6; // Field S2: Ljava / Lang / String; 20: ALOAD_0 21: LDC # 2; // String S1 23: Putfield # 4; // Field S1: LJAVA / Lang / string; 26: returnpublic debug.test (java.lang.string); code: 0: ALOAD_0 1: InvokeSpecial # 7; // method "" :() V 4: New # 8; // Class Java / Lang / RuntimeException 7: DUP 8: InvokeSpecial # 9; // Method Java / Lang / RuntimeException. "" :() V 11: Athrow

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 :( ljava / lang / string;) V 9: POP 10: Return

}

We once again saw the javap-implemented bug, although there is a "": (ljava / language / string;) V signature can explain that each constructor corresponds to a different , but the runtime is still positioned. " "() V method: InvokeSpecial # 8; // method java / lang / runtimeException." ":: () V, and call in the main method is obviously" ": (Ljava / lang / string;) v.

But we see that Test () is called due to TEST (String S); so "":: (ljava / language / string;) V is no longer initialized to instance variables and initialization blocks:

Public debug.test (java.lang.string); code: 0: ALOAD_0 1: InvokeSpecial # 7; // method "" :() v 4: New # 8; // Class Java / Lang / RuntimeException 7 : DUP 8: InvokeSpecial # 9; // Method Java / Lang / RuntimeException. "": () V 11: Athrow, if the two constructor is independent, each construct method is executed before calling Call of variables and initial blocks:

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. "":: () V 4: ALOAD_0 5: ALOAD_0 6: LDC # 2; ////// String S1 8: Invokevirtual # 3; // Method RT: (Ljava / Lang / String;) Ljava / Lang / String; 11: Putfield # 4; // Field S1: Ljava / Lang / String; 14: ALOAD_0 15: LDC # 5; // String S2 17: Putfield # 6; // Field S2: Ljava / Lang / String; 20: LDC # 7; // String S3 22: ASTORE_1 23: ALOAD_0 24: LDC # 2; // String S1 26: Putfield # 4; // Field S1: Ljava / Lang / String; 29: Return

Public debug.test (java.lang.string); Code: 0: ALOAD_0 1: InvokeSpecial # 1; // Method Java / Lang / Object. "" :() V 4: ALOAD_0 5: ALOAD_0 6: LDC # 2; // String S1 8: Invokevirtual # 3; // method rt: (ljava / lang / string;) ljava / lang / string; 11: Putfield # 4; // Field S1: Ljava / Lang / String; 14 : ALOAD_0 15: LDC # 5; // String S2 17: Putfield # 6; // Field S2: Ljava / Lang / String; 20: LDC # 7; // String S3 22: ASTORE_2 23: New # 8; // Class Java / Lang / RuntimeException 26: DUP 27: InvokeSpecial # 9; // Method Java / Lang / RuntimeException. "" :() V 30: AthrowJava.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 :( ljava / lang / string;) V 9: POP 10: Return

}

Tired, write here first.

转载请注明原文地址:https://www.9cbs.com/read-95956.html

New Post(0)