JAVA new子类的时候是否会创建父类

JAVA new子类的时候是否会创建父类

问题:

  1. 学习java基础的记得自己死记硬背这句话:
    1. 子类创建的时候,会先隐式调用父类无参数构造方法(如果父类没有构造方法,系统则会给父类默认添加无参构造)
    2. 自己测试过,如果父类有参构造,没有无参构造,子类必须显示调用父类有参构造(如果不调用会报错)
    3. 结论:子类必须调用父类的构造方法
  2. 问题: 调用父类构造方法==new 父类?

理论分析

  1. 从类的加载过程来说:
    1. 通过类全定名加载这个类class文件(或者满足class文件规范的二进制流)
    2. 验证
    3. 准备
    4. 解析(这个过程是一个递归过程,会递归加载父类class文件,和字段,接口,递归是从 第一步到第四部)
    5. 初始化(真真new对象)
    6. 使用
    7. 销毁
  2. 分析上面步骤
    1. 1-4部 是一个递归加载class文件,生成对应Class对象(intanceKlass)
    2. 初始化这部到底会不会new 父类呢?
      1. 个人想法: 应该不会,就算会,也只会new一份父类对象,让子类共同使用,因为父类公共项,在只有无参构造的时候的值基本不会变动的,也就是可以理解成一个常量,为什么要重复创建,浪费性能,
      2. 自己得出来的结论:
        1. 不会创建的可能性很大(每个对象,都要分配对象头,实例参数,补位,浪费很多空间)
        2. 就算创建,也应该在复用的基础上面
        3. 假设不创建: 至少解决 对象头的空间

大胆猜想,拿实践求证

  1. 上代码:

    public class A {
    
        private String a;
    
        public A(String a){
            this.a=a;
            System.out.println(this);
        }
    
        public static void main(String[]args){
            B b=new B("b");
    
        }
    }
    
    public class B extends  A {
    
        private String b;
    
        public B(String b) {
            super(b+b);
            this.b=b;
            System.out.println(this);
        }
    }
  2. 运行结果:
    运行结果
  3. 分析结果:
    父类里面的构造方法 this 和子类构造方法 this 引用指向的对象都是相同的
  4. 结论:
    子类构造的时候一定会调用父类构造器,初始化公共属性的值
    调用构造器!= 会构造父类对象

通过HSDB验证

  1. HSDB 使用教程:地址
  2. 注意:需要把 sawindbg.dll 文件复制到 jre/bin jkd/bin两个目录下,要不会报错
  3. 代码:

    public class A {
    
        private String pri;
    
        protected  String pro;
    
        public String pub;
    
    
        public A(){
            this.pri="pri";
            this.pro="pro";
            this.pub="pub";
        }
    }
    public class B extends A {
    
        private String b;
    
        public  B(){
            this.b="b";
        }
    }
    public class Main {
        public static void main(String[] args) {
            A a = new B();
            System.out.println(a);
        }
    }
    
  4. 查询结果:
    这里写图片描述
    这里写图片描述
  5. 总结:通过HSDB证明我上面推论,父类会被加载,但是不会被初始化,子类会持有父类的公共属性

附带问题

  1. 为什么 构造方法,可以用this,this还有指向的地址呢?
  2. 分析:
    1. 初始化一个对象的时候,肯定是先开辟一个物理空间,开辟好后,把物理空间地址,返回给this,这个时候,在通过this对物理空间具体值进行修改
    2. 开辟 ->赋值,所以,在赋值前,对象已经真是存在 在内存里面了,只是对象的值,还没初始化

猜你喜欢

转载自blog.csdn.net/luohongtuCSDN/article/details/81040490
今日推荐