构造器初始化

构造器初始化

先来看看下面这段代码:

public class ConstructTest {

    private int n;

    public ConstructTest() {
        //通过构造器来初始化
        n = 5;
    }
}

以上代码通过无参构造器来对全局变量 n 进行初始化,n 首先会被赋值为 0,然后变成 5。对于基本类型和对象引用,编译器不会强制要使用构造器或者别的方式来对其进行初始化,因为它们在定义的时候初始化就已经得到了保证。例如:int 型的初始值为 0,Random 型的初始值为 null。

为了验证初始化顺序,我们看看下面这段:

public class ConstructTest {

    public ConstructTest() {
        //第二次被初始化
        t = new Table(11);
    }
    //定义的时候被第一次初始化
    Table t = new Table(1);

    Table t2 = new Table(2);

    public static void main(String[] args) {
        ConstructTest c = new ConstructTest();
    }
}

class Table{
    //有参构造器
    public Table(int num) {
        System.out.println("the num of table: " + num);
    }
}

以上代码的输出结果是:
the num of table: 1
the num of table: 2
the num of table: 11

我们可以看到 Table 的对象都会在调用构造器之前得到初始化,其中对象 t 被初始化了两次,一次是在调用构造器之前,也就是定义的时候,另一次是在调用期间(第一次引用的对象将被丢弃,并作为垃圾回收)。

静态变量初始化

static 修饰的变量即为静态变量,无论创建多少个对象,静态变量都只占用一份存储区域,而且 static 关键字不能作用于局部变量。

public class StaticTest {

    public static void main(String[] args) {
        new Book();
        new Book();
    }
}

class Paper{
    //有参构造器
    public Paper(int n) {
        System.out.println("paper construtor: " + n);
    }

    public void p(){
        System.out.println("p method");
    }
}

class Book{
    //变量 p1
    Paper p1 = new Paper(1);
    public Book() {
        System.out.println("book construtor");
        p2.p();
    }
    //静态变量 p2
    static Paper p2 = new Paper(2);
}

输出结果是:
paper construtor: 2
paper construtor: 1
book construtor
p method
paper construtor: 1
book construtor
p method

我们可以看到初始化的顺序,首先是静态变量,然后是非静态变量,然后是构造器。当 Book 的对象创建的时候,静态变量 p2 就会被初始化,并且无论之后创建多少个 Book 的对象,p2 不会再次被初始化。

非静态实例初始化

public class Cats {

    Cat cat;

    {
        cat = new Cat(1);
    }

    public Cats() {
        System.out.println("cats contrutor");
    }

    public Cats(int num) {
        cat.test(num);
    }

    public static void main(String[] args) {
        new Cats();
        new Cats(2);
    }
}

class Cat {
    public Cat(int num) {
        System.out.println("cat constructor:" + num);
    }
    public void test(int num){
        System.out.println("test methos: " + num);
    }
}

输出结果:
cat constructor:1
cats contrutor
cat constructor:1
test methos: 2

从打印结果我们可以看到,初始化顺序是,非静态变量,非静态代码块,然后才是构造器。而且每次调用构造器(无论是哪一个构造器)时,非静态变量和非静态代码块都会初始化一次。

对象创建过程

我们现在来总结一下对象的创建过程:

  1. 当我们首次访问类(以 Book 为例)的对象时,或者类的静态方法/静态变量时,Java 解析器会查找类路径,以查找类文件;
  2. 然后载入 Book.class,有关静态初始化动作都会执行,因此,静态初始化只会在 Class 对象首次加载的时候执行一次。
  3. 当通过 new 关键字来创建 book 对象的时候,将在堆上为 book 对象分配足够的存储空间。
  4. 这块存储空间会被清零,自动将 book 对象中的所有成员变量进行初始化,如果是基本类型会被设置为默认值,如果是对象引用会被设置为 null。
  5. 执行所有出现于字段定义处的初始化动作。
  6. 执行构造器。
欢迎关注公众号 一盐难进

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值