Java 类加载顺序与成员变量初始化
2017-09-15 10:36
357 查看
类加载顺序
父类静态代码块(包括静态初始化块,静态属性,但不包括静态方法)子类静态代码块(包括静态初始化块,静态属性,但不包括静态方法 )
父类非静态代码块( 包括非静态初始化块,非静态属性 )
父类构造方法
子类非静态代码块 ( 包括非静态初始化块,非静态属性 )
子类构造方法
静态块:用static声明,JVM加载类时执行,仅执行一次。有多个静态变量或块时,按声明顺序加载
构造块:类中直接用{}定义,每一次创建对象时执行
执行顺序优先级:静态块>main()>构造块>构造方法
静态块的例子:
public class B { public static B t1 = new B(); public static B t2 = new B(); { System.out.println("构造块"); } static { System.out.println("静态块"); } public static void main(String[] args) { B t = new B(); } }
构造块 构造块 静态块 构造块
构造块的例子:
类变量、实例变量的初始化比较相似,对于实例变量有一个例子
public class RAMTest { { price = 3.4;//①--非静态语句块 } public RAMTest(double price) { this.price = price;//②--构造函数 } double price = 2.0;//③--声明语句并赋值 }
本例中对实例变量price的初始化有三处,执行顺序为:
--③中price变量声明[price=0.0] --①中price变量赋值[price=3.4] --③中price变量赋值[price=2.0] --②中price构造方法中赋值
需要注意的是,虽然非静态语句初始块中的price变量的赋值在声明之前,但实际上执行的时候会先执行变量的声明,再按代码顺序执行变量值的赋值动作,然后再进行构造方法对实例的初始化构造。
这三种实例变量的初始化语句经过编译器处理后,都会合并到构造器中去,其中定义变量语句转换得到的赋值语句、初始化块中的语句转化得到的赋值语句,总是位于构造器的所有语句之前。合并后两种赋值语句的顺序保持他们在源码中的顺序。
成员变量初始化
如果我们不做任何初始化工作,变量具有什么默认值,或者是否具有默认值? 其实,成员变量在创建时,系统会为其分配一个默认值。不同类型的变量,默认值也不相同。例:
public class DefaultValue { // 实例成员变量 private boolean bool; private byte b; private short s; private char c; private int i; private long l; private float f; private double d; private String str; private String[] strArray; // 静态成员变量 private static boolean boolStatic; private static byte bStatic; private static short sStatic; private static char cStatic; private static int iStatic; private static long lStatic; private static float fStatic; private static double dStatic; private static String strStatic; private static String[] strArrayStatic; public void printInstanceField() { System.out.println("实例成员变量默认值:"); System.out.println("boolean:" + bool); System.out.println("byte:" + b); System.out.println("short:" + s); System.out.println("char:" + c); System.out.println("int:" + i); System.out.println("long:" + l); System.out.println("float:" + f); System.out.println("double:" + d); System.out.println("String:" + str); System.out.println("String[]:" + strArray); } public static void printStaticField() { System.out.println("静态成员变量默认值:"); System.out.println("boolean:" + boolStatic); System.out.println("byte:" + bStatic); System.out.println("short:" + sStatic); System.out.println("char:" + cStatic); System.out.println("int:" + iStatic); System.out.println("long:" + lStatic); System.out.println("float:" + fStatic); System.out.println("double:" + dStatic); System.out.println("String:" + strStatic); System.out.println("String[]:" + strArrayStatic); } public static void main(String[] args) { DefaultValue dv = new DefaultValue(); dv.printInstanceField(); dv.printStaticField(); } }
运行结果:
实例成员变量默认值: boolean:false byte:0 short:0 char: int:0 long:0 float:0.0 double:0.0 String:null String[]:null 静态成员变量默认值: boolean:false byte:0 short:0 char: int:0 long:0 float:0.0 double:0.0 String:null String[]:null
在本程序中声明了各种类型,分别为8种基本数据类型、引用类型、数组类型。并且声明为两组,一组为实例变量,一组为静态变量。然后一次输出两组数据的值。
数组类型与引用类型的默认值相同,都为null,实际上,数组就是一种特殊的类(对象),所以数组类型的变量也就是引用类型的变量。从结果可知,相同类型的实例变量与静态变量默认值是相同的。
这里有一点奇怪,char类型变量后面什么也没有输出。不过,这并不是char类型变量没有默认值,而是默认值为“空字符”,也就是‘\u0000’,数值为0,我们可以证明一下。
例:
public class CharDefaultValue { static char c; public static void main(String[] args) { System.out.println((int) c); System.out.println(c == '\u0000'); } }
运行结果:
0
true
局部变量使用前必须初始化
相对于成员变量,局部变量没有默认值(不管是什么类型),如果试图使用一个局部变量的值,而这个局部变量尚未初始化,就会产生编译错误,例如:
public static void main(String[] args) { int value; System.out.println(value); }
错误提示:
The local variable value may not have been initialized
特殊情况:数组
但是,对于数组而言,如果数组使用new在堆上分配了空间,则数组的元素就会获得默认值,即使数组变量为局部变量也是如此。
例:
public static void main(String[] args) { int[] value = new int[10]; System.out.println(value[0]); }
将会输出value[0]的默认值“0”。可以把数组的元素看作是数组的成员变量(实际上不是),当数组分配空间时,数组的元素(行为类似于成员变量)就可以获得默认的初始值。不过,对于局部变量数组本身(即value),如果没有初始化,同样没有默认值。
转自:
http://blog.csdn.net/u012552052/article/details/45318389
http://blog.csdn.net/zhuhai__yizhi/article/details/51980176
相关文章推荐
- Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序
- java基础,静态变量,静态初始化块,初始化快,成员变量的初始化顺序
- java堆空间子父类顺序(1)开辟空间都为0(2)父类初始化不管值(3)把成员变量赋值的显示初始化(4)构造代码块(5)子函数初始化
- java成员变量的初始化顺序
- java成员变量的初始化顺序
- Java成员变量初始化顺序
- Java中创建对象时,初始化成员变量的代码的执行顺序
- Java 代码块、成员变量初始化、构造函数初始化顺序
- java 成员变量 静态变量代码块 静态代码快加载顺序
- JAVA类在初始化时成员的加载顺序
- Java的静态变量,成员变量,静态代码块,构造块的加载顺序
- Java中成员变量的初始化顺序浅析
- java基础---静态变量,成员变量,局部变量及类的初始化顺序
- Java 构造方法和成员变量初始化顺序
- Java类加载过程后,成员变量的初始化。
- 从类变量成员初始化顺序,理解java语法[1]
- java学习个人笔记---类成员变量初始化顺序
- java中成员 变量的初始化顺序
- Java中构造代码块和成员变量初始化的顺序关系
- Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序