静态变量会在main方法执行前就开始加载。顺序为:
1.按代码书写顺寻在内存上开辟引用地址,并给这些引用设置为默认值。其中:
对于基本类型,初始值为0.如int等。
对于复合类型,初始值为null。如String、自定义类等。
2.按代码书写顺序进行初始化,即赋值操作。将实例赋值给引用。
下面举例说明:
代码:
第一步,按代码书写顺序,在内存上为静态变量的引用开辟地址。程序中有两个静态变量:t和i。并为这两个变量设置为默认值。t的类是T,是自定义类,因此默认值为null。i的类是int,是基本数据类型,默认值为0.
第二步,按代码书写顺序,进行初始化操作。
首先是为t进行初始化操作:t的初始化操作为构造一个T类对象,并赋值个t。而T的构造方法中,对i变量进行了+1操作,而i此时的值是int类型的默认值,也就是0,故进行+1操作后变成了1。之后构造方法结束,一个T类的实例生成,代替了t的默认值null。此时t的值变成了刚刚构造的T类实例。而i的值是1。
然后对i进行初始化操作:将0赋值给i。i的值又变成了0,代替了刚才初始化t时赋值的0。
第三部,执行主方法。打印i的值。
因此输出结果为:0。
拓展一:由于执行了给i进行了赋值操作,因此0覆盖了T构造方法中赋值给i的1.如果不进行赋值操作,也就是写成:public static int i;则不会对i进行初始化操作,也就无法覆盖T构造方法造成的结果。故输出结果为1.
拓展二:由于按照书写顺序,给t的初始化操作写在i的初始化操作之前,因此i的初始化操作覆盖了t的初始化操作,故最后i的值是0.如果颠倒书写顺寻,先让i进行初始化操作,则t进行初始化操作时,T的构造方法会给i赋值为1,覆盖了i之前初始化的值0.故输出结果为1.
1.按代码书写顺寻在内存上开辟引用地址,并给这些引用设置为默认值。其中:
对于基本类型,初始值为0.如int等。
对于复合类型,初始值为null。如String、自定义类等。
2.按代码书写顺序进行初始化,即赋值操作。将实例赋值给引用。
下面举例说明:
代码:
public class Test {
public static T t = new T();
public static int i = 0;
public static void main(String args[]){
System.out.println(i);
}
}
class T{
public T(){
Test.i++;
}
}
第一步,按代码书写顺序,在内存上为静态变量的引用开辟地址。程序中有两个静态变量:t和i。并为这两个变量设置为默认值。t的类是T,是自定义类,因此默认值为null。i的类是int,是基本数据类型,默认值为0.
第二步,按代码书写顺序,进行初始化操作。
首先是为t进行初始化操作:t的初始化操作为构造一个T类对象,并赋值个t。而T的构造方法中,对i变量进行了+1操作,而i此时的值是int类型的默认值,也就是0,故进行+1操作后变成了1。之后构造方法结束,一个T类的实例生成,代替了t的默认值null。此时t的值变成了刚刚构造的T类实例。而i的值是1。
然后对i进行初始化操作:将0赋值给i。i的值又变成了0,代替了刚才初始化t时赋值的0。
第三部,执行主方法。打印i的值。
因此输出结果为:0。
拓展一:由于执行了给i进行了赋值操作,因此0覆盖了T构造方法中赋值给i的1.如果不进行赋值操作,也就是写成:public static int i;则不会对i进行初始化操作,也就无法覆盖T构造方法造成的结果。故输出结果为1.
拓展二:由于按照书写顺序,给t的初始化操作写在i的初始化操作之前,因此i的初始化操作覆盖了t的初始化操作,故最后i的值是0.如果颠倒书写顺寻,先让i进行初始化操作,则t进行初始化操作时,T的构造方法会给i赋值为1,覆盖了i之前初始化的值0.故输出结果为1.