java基础知识总结之初始化

一、成员初始化

java尽力保证所有变量在使用前都能得到恰当的初始化。如果方法的局部变量没有初始化,java会出现编译时错误,比如:

但是,类的每个基本类型的数据成员都保证会有一个初始值:

public class Test {
    public static void main(String[] args){
        InitTest it = new InitTest();
        it.printInit();
    }
}

class InitTest {
    boolean b;
    char c;
    int i;
    void printInit(){
        System.out.println("b:  "+b);
        System.out.println("c:  "+c);
        System.out.println("i:  "+i);
    }
}

输出的值为:

b:  false
c:   
i:  0

二、构造器初始化

我们可以使用构造器来进行初始化。在运行的时刻,可以调用方法或执行某些动作来设定初始值,但要牢记:无法阻止自动初始化的进行,他将在构造器被调用之前发生。比如:

public class InitConstructor {
    int i;
    InitConstructor() {
        System.out.println(i);
        i = 7;
        System.out.println(i);
    }

    public static void main(String[] args){
        InitConstructor ic = new InitConstructor();
    }
}

i首先会被置为0,然后被置为7。

在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布在方法之间,它们仍然会在任何方法(包括构造器)被调用之前得到初始化:

class Order {
    Order(int i) {
        System.out.println("Order "+i);
    }
}

class OrderWrap {
    Order order1 = new Order(1);
    OrderWrap() {
        System.out.println("OrderWrap");
        order3 = new Order(33);
    }
    Order order2 = new Order(2);
    void f() {
        System.out.println("f()");
    }
    Order order3 = new Order(3);
}

public class InitOrder {
    public static void main(String[] args){
        OrderWrap o = new OrderWrap();
        o.f();
    }
}

在main方法中调用f()是为了显示初始化已经完成。我们可以看到输出结果:

Order 1
Order 2
Order 3
OrderWrap
Order 33
f()

由输出可见,order3会被初始化两次,第一次在调用构造器前,第二次在调用构造器期间(第一次的引用对象会被丢弃,被垃圾回收器回收)。

接下来我们讨论下静态数据的初始化。我们知道,无论创建多少对象,静态数据都只占用一份存储区域。如果一个属性是静态的基本类型,且没有对他进行初始化,那么他就会获得基本类型的标准初值,如果他是一个对象的引用,那么它的默认初始化值就是null。

class Dog {
    Dog(int i) {
        System.out.println("Dog "+i);
    }
    void f_dog(int i) {
        System.out.println("f_dog "+i);
    }
}

class People {
    static Dog dog1 = new Dog(1);
    People() {
        System.out.println("People()");
        dog2.f_dog(1);
    }
    void f_people(int i) {
        System.out.println("f_people "+i);
    }
    static Dog dog2 = new Dog(2);
}

class Animal {
    Dog dog3 = new Dog(3);
    static Dog dog4 = new Dog(4);
    Animal() {
        System.out.println("Animal()");
        dog4.f_dog(2);
    }
    void f_animal(int i) {
        System.out.println("f_animal "+i);
    }
    static Dog dog5 = new Dog(5);
}

public class InitTest {
    public static void main(String[] args){
        System.out.println("----------------------");
        new Animal();
        System.out.println("----------------------");
        new Animal();
        people.f_people(1);
        animal.f_animal(1);
    }
    static People people = new People();
    static Animal animal = new Animal();
}

大家可以先试着梳理下输出结果:

Dog 1
Dog 2
People()
f_dog 1
Dog 4
Dog 5
Dog 3
Animal()
f_dog 2
----------------------
Dog 3
Animal()
f_dog 2
----------------------
Dog 3
Animal()
f_dog 2
f_people 1
f_animal 1

由输出可见,静态初始化只有在必要的时候才会进行。如果不创建People对象,也不引用pelple.dog1或者people.dog2,那么静态的Dog dog1和dog2永远不会被创建。只有在第一个People对象被创建(或者第一次访问静态数据)的时候,他们才会被初始化。此后,静态对象不会再次被初始化。

初始化的顺序是先静态对象,而后是“非静态”对象。我们总结一下对象的创建过程:

1、即使没有显式地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态属性首次被访问时,java解释器必须查找类路径以定位Dog.class文件。

2、然后载入Dog.class,有关静态初始化的所有动作都被执行。因此,静态初始化只在Class对象首次加载的时候进行一次。

3、当用new Dog()创建对象时,首先将在堆上为Dog对象分配足够的存储空间。

4、这块存储空间会被清零,这就自动的将Dog对象中的所有基本类型数据都设置成了默认值,而引用对象则被设置成了null。

5、执行所有出现于字段定义处的初始化动作。

6、执行构造器。

那么非静态变量的初始化是什么样的呢?我们看如下代码:

class Dog {
    Dog(int i) {
        System.out.println("Dog "+i);
    }
    void f_dog(int i) {
        System.out.println("f_dog "+i);
    }
}

public class Dogs {
    Dog dog1;
    Dog dog2;
    {
        dog1 = new Dog(1);
        dog2 = new Dog(2);
    }
    Dogs() {
        System.out.println("Dogs()");
    }
    Dogs(int i) {
        System.out.println("Dogs "+i);
    }
    public static void main(String[] args){
        System.out.println("----------------------");
        new Dogs();
        System.out.println("----------------------");
        new Dogs(1);
    }
}

输出结果:

----------------------
Dog 1
Dog 2
Dogs()
----------------------
Dog 1
Dog 2
Dogs 1
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值