通过字节码深入了解创建对象的过程

    技术2022-07-10  157

    package shixun.test; public class Test2643 { public static void main(String[] args) { Person person = new Person(); } } class Tag { int i; public Tag(int i) { this.i = i; //System.out.println("Tag(" + this.i + ")"); } } class Person { Tag t1 = new Tag(1); String name; Tag t2 = new Tag(2); int age; String sex; Boolean b1 = new Boolean(false);//Boolean.FALSE; //Tag t3 = new Tag(3); public Person() { super(); //System.out.println("构造器Person()被调用"); sex = "Male"; //System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex); } public Person(String theName) { //调用构造器Person() this(); //System.out.println("构造器Person(String theName)被调用"); name = theName; //System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex); } public Person(String theName, int theAge) { //调用构造器Person(String theName) this(theName); //System.out.println("构造器Person(String theName,int theAge)被调用"); age = theAge; //System.out.println("name=" + name + " ,age=" + age + " ,sex=" + sex); } //初始化块 { this.name = "Tony Blair"; this.age = 50; this.sex = "Female"; System.out.println("初始化块执行后:name=" + this.name + " ,age=" + this.age + " ,sex=" + this.sex); System.out.println(this.t3); } Tag t3 = new Tag(3); }

    通过反编译javap -v Person 命令来看一下Person这个对象的字节码文件。

    上面的字节码文件代表虚拟机执行源代码的具体顺序 这个lLineNumberTable对应的是java文件和class文件对应的行数。 根据这张图我们能分析出每次创建对象一定是先开辟空间,给每个属性默认值。然后调用构造方法,但是调用构造方法不代表你就会执行构造方法中的代码,而是先调用父类的构造方法,调用父类的构造方法后面的过程和子类一样就不细说。父类的构造方法执行完毕后,按照顺序初始化属性和执行构造代码块。 这里有个细节,在代码块如果访问该对象的成员变量,如果不加this,只能访问已经被初始化过得成员变量,因为只有初始化完成才会把这个变量放入局部变量表,代码块才能访问到,否则编译不通过,但是如果加了this是一定会访问到,如果没有初始化那么就是默认值。 当上述全部执行完毕后最后再去执行构造方法中的具体代码。

    Processed: 0.015, SQL: 9