构造器初始化

构造器初始化

先来看看下面这段代码:

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. 执行构造器。
欢迎关注公众号 一盐难进

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值