Java拾遗——类的初始化

我们知道一个类需要在一个new操作符下完成类的初始化。

那么,这里面的各个部分到底是怎么样初始化的呢?

一、默认构造器先于任何实例的调用

class Car{
    private int speed;
    public Car(){speed=12;}
    public void tellMeSpeed(){
        System.out.println("my speed is "+speed);
    }
}
public class practice {
    public  static void main(String[] args){
        Car c=new Car();
        c.tellMeSpeed();
    }
}

观察上边的代码。实际上的输出是:my speed is 12

因为默认构造器在这个类已经可以使用之前就已经完成调用了。

二、块部分先于构造器

class Car{
    private int speed;
    public Car(){
        speed=12;
        System.out.println("current speed:"+speed);
    }
    {
        speed=5;
        System.out.println("block init.");
    }
    public void tellMeSpeed(){
        System.out.println("my speed is "+speed);
    }
}
public class practice {
    public  static void main(String[] args){
        Car c=new Car();
        c.tellMeSpeed();
    }
}

观察上边的代码,可以看到有一个“块”在默认构造器的下面。

为了得到初始化顺序,运行这段代码:

block init.
current speed:12
my speed is 12

 

可以看到,块总是在默认构造器之前调用。而且为了解除由于编译器编译时的顺序问题,我把块放到了默认构造器的后面,

但是依然是块初始化最先被调用。

三、静态初始化块在非静态初始化块之前

class Car{
    private int speed;
    private static int id;
    public Car(){
        speed=12;
        System.out.println("current speed:"+speed);
    }
    {
        speed=5;
        System.out.println("block init.");
    }
    static {
        id=111;
        System.out.println("static init block");
    }
    public void tellMeSpeed(){
        System.out.println("my speed is "+speed);
    }
}
public class practice {
    public  static void main(String[] args){
        Car c=new Car();
        c.tellMeSpeed();
    }
}

考虑上述代码,为了观察顺序,运行:

static init block
block init.
current speed:12
my speed is 12

可以看到static初始化块是最先被调用的,但遗憾的是这个块里面只可以初始化静态成员。

为了说明 二,三 部分的区别,可以做一个这样的假设。

首先呢,类加载器(classloader)把我们的.java文件编译后生成了一个个的.class文件。

当我们不对类进行实例化时,它就认为class{...}里的代码是一个构造模板,在用到时再加载。

但是存在static变量时,它就认为这个变量是它的属性,在生成class文件时就初始化了。

所以他们分别是在使用时、生成时创建,所以一定会有创建的顺序static先于其他的了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值