java输出调用构造函数的次数_浅谈 Java 中的初始化

6f0f2985b48ce1617d89202e4ee6733d.png

Java 内存分布

b22dfab1d4479fcca58edb935dc7575a.png

需要注意的是,方法中的参数属于局部变量 ,类似于 String str="字符串" 这样定义的字符串是存放在堆内存中的「字符串常量池」(常量池中不会添加已有成员)中。

String str1 = new String() 内存是直接位于堆中,每一次对象的实例化都会在堆中开辟新的内存空间。

成员变量与局部变量的区别

ee54cbf3d4fe045ed2659a06fe7b9e8d.png

结合代码分析

class Person {
    private String name;
    private int age;

    public Person(){ }
    public Person(String name, int age) { // 两个参数属于局部变量,调用完成后被销毁,且只能在该方法内部访问
        this.name = name;
        this.age = age;
    }

    public void showInfo(){ // 类内部访问成员变量
        System.out.println("name =" + name);
        System.out.println("age = "+age);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.showInfo();
        Person p2 = new Person("hack-hu",18);
        p2.showInfo();
    }
}

输出结果:

// p1 输出缺省值,两个成员变量都被自动初始化
name =null
age = 0
// p2 输出赋值后结果,重载的构造方法在调用完成后销毁
name =hack-hu
age = 18

提示:虽然成员变量会自动完成初始化,但是在定义时或使用前先初始化是个好习惯。

类中数据的初始化顺序

原则:

  • 1、类构造函数调用时,先初始化类中的成员变量,所有成员变量初始化完成后,再执行构造函数代码。
  • 2、父类构造函数完成再执行子类构造函数。
  • 3、静态(static)成员初始化后再初始化非静态成员
  • 4、同一优先级,按照代码的先后顺序执行。

代码实践

定义父类 Person

public class Person {
    private String name;
    private int age;

    static {
        System.out.println("父类静态块代码执行");
    }

    public Person(){
        System.out.println("父类构造函数执行");
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void showInfo(){
        System.out.println("name =" + name);
        System.out.println("age = "+age);
    }
}

定义其旁类 Nationality (国籍)

public class Nationality {
    static {
        System.out.println("旁类静态块执行");
    }
    public Nationality(){
        System.out.println("旁类构造方法执行");
    }
}

定义 Person 子类 Student

public class Student extends Person {
    static Nationality nation= new Nationality();
    static {
        System.out.println("子类静态块执行");
    }
    public Student(){
        System.out.println("子类构造函数执行");
    }
}

输出结果:

父类静态块代码执行
旁类静态块执行
旁类构造方法执行
子类静态块执行
父类构造函数执行
子类构造函数执行

注意,子类中的静态对象 nation,要比父类的构造函数先执行,说明所有的静态成员都要先初始化。当 nation 不为静态时,则先完成父类构造,再初始化子类非静态成员。

总结:实践出真知,对于含糊不清的概念,可以实践一些案例来参照理解。若文章中有错误欢迎指正,欢迎你给出评论,或是默默点点赞给个好看,这都是对我的一种认可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值