<init>()方法,是虚拟机自己调用的,不在我们的程序中显性表示。
那么<init>()的作用是什么?在什么时候被调用?
实际上,JVM为每一个类的每一个构造方法都创建一个<init>()方法,用于初始化实例变量。
我们用一个例子来进行分析:
public class Test{
private String name;
private int age;
public Test(){
}
public Test(String name){
this.name=name;
}
public Test(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
对这个类进行编译之后
利用指令:javap -verbose TestClass对其进行分析:
F:\java_cmd>javap -verbose Test
Classfile /F:/java_cmd/Test.class
Last modified 2016-10-22; size 461 bytes
MD5 checksum c2357af595833a04fc4d51146c91def8
Compiled from "Test.java"
public class Test
SourceFile: "Test.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #5.#20 // java/lang/Object."<init>":(
#2 = Fieldref #4.#21 // Test.name:Ljava/lang/String
#3 = Fieldref #4.#22 // Test.age:I
#4 = Class #23 // Test
#5 = Class #24 // java/lang/Object
#6 = Utf8 name
#7 = Utf8 Ljava/lang/String;
#8 = Utf8 age
#9 = Utf8 I
#10 = Utf8 <init>
#11 = Utf8 ()V
#12 = Utf8 Code
#13 = Utf8 LineNumberTable
#14 = Utf8 (Ljava/lang/String;)V
#15 = Utf8 (I)V
#16 = Utf8 getAge
#17 = Utf8 ()I
#18 = Utf8 SourceFile
#19 = Utf8 Test.java
#20 = NameAndType #10:#11 // "<init>":()V
#21 = NameAndType #6:#7 // name:Ljava/lang/String;
#22 = NameAndType #8:#9 // age:I
#23 = Utf8 Test
#24 = Utf8 java/lang/Object
{
public Test();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object.
":()V
4: return
LineNumberTable:
line 5: 0
line 6: 4
public Test(java.lang.String);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object.
":()V
4: aload_0
5: aload_1
6: putfield #2 // Field name:Ljava/lang/St
9: return
LineNumberTable:
line 8: 0
line 9: 4
line 10: 9
public Test(int);
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object.
":()V
4: aload_0
5: iload_1
6: putfield #3 // Field age:I
9: return
LineNumberTable:
line 12: 0
line 13: 4
line 14: 9
public int getAge();
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #3 // Field age:I
4: ireturn
LineNumberTable:
line 17: 0
}
我们可以从Class文件中发现,对于Test类中的每一个构造方法,JVM都有一条调用<init>()方法的指令存在