在内存中创建对象时,是将子类和父类的属性所需空间全部分配好以后再给每个空间初始化,还是先给父类分配空间以后就初始化,再给子类分配空间然后对子类属性进行初始化?


public class ExtendsTheory {
    public static void main(String[] args) {
        Son son = new Son();
    }
}

class GrandPa { //爷类
    String name = "大头爷爷";
    String hobby = "旅游";
}

class Father extends GrandPa {//父类
    String name = "大头爸爸";
    private int age = 39;

    public int getAge() {
        return age;
    }
}

class Son extends Father { //子类
    String name = "大头儿子";
}

在段代码中创建son对象时,先依次加载object类,grandpa类,father类,son类的类信息以后,在堆中分配空间分别存储爷类,父类和子类的属性信息,在这个过程中是统一先将爷类,父类,子类属性所需的空间都分配好再统一对其进行初始化,还是先分配爷类属性的空间并对爷类属性进行初始化,再分配父类属性所需空间并初始化?

首先“在内存中创建对象时,..........”,你提问的问题就有问题。具体是啥,且听我描述。
1、首先对象的创建和加载不是同步进行的,具体对象的大小是由编译器决定,将具体值放在对象头中,在创建对象的时候使用,加载对象是由对象加载子系统进行加载的,加载到JVM的元空间(JDK8叫元空间,之前叫方法区)区域,一般情况下,加载是早于创建对象的。

img

2、答案是:由AppClassLoader对象先加载爷类、父类、孙子类。当你创建孙子类时,(Son son = new Son();),就会在JVM里面的堆内存中创建爷类对象并初始化,再创建父类对象并初始化,最后创建孙子类对象,并初始化。

加载顺序:父类静态变量、父类静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造函数、子类非静态变量、子类非静态代码块、子类构造函数

创建对象,子类和父类是在同一块内存,大小取决于子类和父类的对象属性。