一.什么是向前引用?
有过C++编程经验的就会知道,一个变量或者方法总是需要先声明再使用。那么Java里面如下的代码是可以的吗?
public class GoFirst{
int m = n;//illegal forward reference,无法编译,报错
int n = 1;
}
也许我们可以做一些迷惑编译器的代码以达到前向引用的目的。
public class GoFirst{
int m = method();;//可以编译
int n = 1;
int method() {return n; }
}
public static void main(String[] args) {
GoFirst goFirst=new GoFirst();
System.out.println(goFirst.m);//0,首先按照成员声明顺序装载成员字段,此时n未被加载,为默认值
System.out.println(goFirst.method());//1
System.out.println(goFirst.n);//1
}
在GoFirst类被初始化的时候,第一次的初始化:此时的GoFirst的所有成员变量均被初始化为各种数据类型的初始值,此时的成员变量已经为默认值(int类型的默认值为0,此次初始值均为编译器给定的默认值),第二次的初始化:按照成员变量声明的顺序设置我们想要初始值。如m先被设置为method()的返回值,再初始化n的值为1。
下面是《Java编程思想第四版》中对象创建过程的描述,假设有一个Dog类:
1.首次创建Dog的对象时或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件
2.载入Dog.class(这将会创建一个Class对象)文件,有关静态初始化的所有动作都会执行,静态初始化只在Class对象首次加载的时候进行一次
3.当用new Dog()创建对象的时候,首次将在堆上为Dog对象分配足够的存储空间
4.将这片存储空间清零,这就自动的将Dog对象的基本数据类型都设置为了默认值,而引用则被设置为了null
5.执行所有出现于字段定义处的初始化动作
6.执行构造器
参考资料:
《Java编程思想第四版》