对象的创建过程-实例变量与代码块实例初始化(二)

2019-03-26  本文已影响0人  小尾巴1024

1、我们在定义或声明实例变量的时候,可以通过为实例变量赋值或是通过代码块赋值,如果我们以这两种方式对实例变量进行初始化,那这两种初始化方式将会在构造函数执行前先执行。
实际上,如果我们对变量直接赋值或是通过代码块对其赋值,那么编译器会将其中的代码放到类的构造函数中去,
并且这些代码会被放在对超类构造函数的调用语句之后 (java要求构造函数的第一条语句必须是超类构造函数的调用语句),构造函数本身代码之前 。如下例子:

public class Student {
    /**
     * 对变量直接赋值会在构造函数执行前先执行
     */
    private int num1 = 1;
    private int num2 = num1+1;
    public Student(int var) {
        System.out.println(num1);
        System.out.println(num2);
        this.num1 = var;
        System.out.println(num1);
        System.out.println(num2);
    }
    /**
     * 代码块会在构造函数执行前先执行
     */
    {
        num2 += 3;
    }
    public static void main(String[] args) {
        new Student(8);  //输出1、5、8、5
    }
}

2、需要注意的是java是按照编程顺序来执行实例变量初始化器和实例变量初始化器中的代码的,并且不允许执行顺序靠前的实例代码块初始化在顺序靠后的实例变量。如下:

public class Student {
    {
        j = i;  //编译不通过
    }
    private int i = 1;
    private int j;
}
public class Student {
    private int j = i;   //编译不通过
    private int i = 1;
}

上面两种情况编译都不通过。编译是会提示我们使用一个未经定义的变量。之所以这么做是因为要保证一个变量在使用之前已经被初始化。
但是我们仍然可以避开这种语法检查。如下:

public class Student {
    private int j = getI();
    private int i = 1;

    public Student() {
        i = 2;
    }

    public int getI() {
        return i;
    }
    public static void main(String[] args) {
        Student stu = new Student();
        System.out.println(stu.j);   //输出0,可以知道j被赋予了i的默认值0,并且该操作发在实例i初始化之前和构造函数执行前
    }
}

参考:https://blog.csdn.net/justloveyou_/article/details/72466416

上一篇 下一篇

猜你喜欢

热点阅读