Order classification of Object instantiation: Java, Base date: 2012-11-08ticmy http://www.ticmy.com/?p=302
There are several ways you might create an object:
1, through the new keyword, such as new Object ();
2, through some reflection class newinstance method, such as Class#newinstance, constructor#newinstance;
3, if the object is cloneable, through the Clone method;
4, through the objectinputstream#readobject of deserialization;
These are the ways in which a Java program can create objects, and there are some places in the JVM that implicitly create objects, such as:
1, start a class, the parameters of the main method string array is created implicitly, if you specify one or more string objects, but also to create these string objects;
2. When reading a class binary data, create an object corresponding to the Java.lang.Class class;
3. Stringbuffer/stringbuilder objects may be created when a string variable is connected using "+";
And so on
So, what is the order of execution of the constructor, instance variable, parent class constructor, parent instance variable, and so on, when you create an object in a program by using new or newinstance (which means that the object is created in both ways)?
When the object is created, the memory is allocated first, all the instance variables are the default values, and the instance variables are initialized, the method calls are constructed, and so on. For class variables, the class is loaded before the object is created, and it is ignored to avoid interference.
Let's start with an example:
public class Init {
public static void main(String[] args)
throws Exception {
S s =
new S();
System.out.println(s.getV2());
}
}
class P {
private int v1 =
5
;
private int v2 = getV1();
public P()
throws Exception {
System.out.println(
"P"
);
}
public int getV1() {
return v1;
}
public int getV2() {
return v2;
}
}
class S
extends P {
private int value1 =
4
;
public int getV1() {
return value1;
}
public S()
throws Exception {
this
(
"S()"
);
}
public S(String msg)
throws Exception {
System.out.println(msg);
}
public S(
int v)
throws Exception {
super
();
System.out.println(
"abc"
);
}
}
|
The results of the implementation are as follows:
PS () 0
The value of call S.GETV2 () is 0, what is the internal mechanism? Get to know something else first.
When compiling the code, a corresponding method is generated for each constructor method called <init>. But it does not directly use the constructor as the content of the <init> method, it has this rule:
If the first statement in the constructor method calls the other constructor methods of this class through this, such as the first construction method of class S, its complete method body is the corresponding method body of the <init> method. The compiler does not add a super call for it.
If the first statement in the constructor method does not call the other constructor methods of this class through this, the <init> method body is composed in the following order:
1, Super class <init> method call. If the superclass constructor method is explicitly called, the corresponding superclass <init> method will be used, and if there is no write, the compiler will generate a call to the superclass-free method of non-reference <init>;
2, the instance variable initialization code, according to the instance variable in the class to appear the order;
3, the other method in the construction method body (if the first sentence is super (...) Called, the sentence is not included).
If the construction method contains super (...) Or this (...) Called, they can only be used as the first statement of the constructed method, meaning that even try...catch cannot have one. Because the first statement must be, so super (...) And this (...) Calls are not to appear together.
The byte codes for each <init> method are obtained by Javap-c s decompile as follows:
public S()
throws java.lang.Exception;
Code:
0
: aload_0
1
: ldc #
2
// String S()
3
: invokespecial #
3
// Method "<init>":(Ljava/lang/String;)V
6
:
return public S(java.lang.String)
throws java.lang.Exception;
Code:
0
: aload_0
1
: invokespecial #
4
// Method P."<init>":()V
4
: aload_0
5
: iconst_4
6
: putfield #
1
// Field value1:I
9
: getstatic #
5 // Field java/lang/System.out:Ljava/io/PrintStream;
12
: aload_1
13
: invokevirtual #
6
// Method java/io/PrintStream.println:(Ljava/lang/String;)V
16
:
return
public S(
int
)
throws java.lang.Exception;
Code:
0
: aload_0
1
: invokespecial #
4
// Method P."<init>":()V
4
: aload_0
5
: iconst_4
6
: putfield #
1
// Field value1:I
9
: getstatic #
5
// Field java/lang/System.out:Ljava/io/PrintStream;
12
: ldc #
7
// String abc
14
: invokevirtual #
6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
17
:
return
|
As you can see, in the first construction method s () of class S, the bytecode shows only the <init> (string) method that invokes this class, as can be seen from the corresponding <init> bytecode of the second constructor s (string). Although not with super (...) Explicitly call the constructor of the superclass, or the compiler generates an offset of 0,1 to call the <init> method of the superclass, the instruction with an offset of 4,5,6 is assigned a value of 4 to the variable value1, followed by the construction method body-the only one printed statement; see also S (int) The corresponding <init> method, the first statement of the construction method is super (...) Call, which corresponds to an offset of 0,1 in <init>, an offset of 4,5,6 is assigned a value of 4 for the instance variable value1, and the last is the print string ABC.
And look at the P-decompile construct method body:
public P()
throws java.lang.Exception;
Code:
0
: aload_0
1
: invokespecial #
1
// Method java/lang/Object."<init>":()V
4
: aload_0
5
: iconst_5
6
: putfield #
2
// Field v1:I
9
: aload_0
10
: aload_0
11
: invokevirtual #
3
// Method getV1:()I
14
: putfield #
4
// Field v2:I
17
: getstatic #
5 // Field java/lang/System.out:Ljava/io/PrintStream;
20
: ldc #
6
// String P
22
: invokevirtual #
7
// Method java/io/PrintStream.println:(Ljava/lang/String;)V
25
:
return
|
An offset of 0,1 is called the <init> method of the object, which is the superclass of class p, the instruction 4,5,6 is assigned a value of 5, and the instruction 9,10,11,14 is to get the value for the instance variable v2 and assign a value, and the remainder is the print string p.
As can be seen from the analysis of the above-mentioned construction methods and corresponding <init> methods, they are all in accordance with the rules described in the previous article. So for the example at the beginning of this article, the value of v2 is 0, so we can analyze:
1, new S () is called the S class of the <init> () method, it calls the class of the <init> (String) method, in this <init>, first to call the superclass, that is, the <init> () p Method, P's <init> () method again calls the P's Super class object's <init> () method, then assigns the value to the V1,V2, the V2 assignment is called getV1 (), and this method is a polymorphic method, It will call the GetV1 method of the class of the new object, that is, the getV1 in Getv1,s in S returns the value of Value1, and the value1 assignment has not been done yet, so the default value of 0 is returned.
Thus, the order of the entire creation of the object is clear.
Order of Object Instantiation