`

关于Java类成员变量加载的一个实验

阅读更多

Java类中,静态初始化器,构造函数,成员变量的加载顺序,一直没有仔细研究过。细节较不准确,所以编程吃了暗亏,纠结了几个小时才发现隐藏的错误。

于是自己做了一个小测验,算是祝自己理解Java类成员变量加载顺序这个问题吧。

 

测试代码如下:

 

 

package com.javaeye.aspnetdb;
/**
 * 
 * @author aspnetdb 周洋
 * 父类
 */
public class OrderFather {
	
	public static String strMsg = "父类Msg";
	
	static {
		System.out.println("父类静态初始化器");
		System.out.println("父类成员变量=" + strMsg);
	}
	public OrderFather() {
		System.out.println("父类的构造函数");
		System.out.println("父类构造函数中,父类成员变量=" + strMsg);
	}
	
	public void say() {
		System.out.println("父类说点什么,子类还是父类=" + strMsg);
	}
	
	
}

 

package com.javaeye.aspnetdb;
/**
 * 
 * @author aspnetdb 周洋
 * 子类
 */
public class OrderSon extends OrderFather{

	public static String strMsg = "子类Msg";
	
	public OrderSon(){
		System.out.println("子类构造函数");
		System.out.println("构造函数中,子类类成员变量=" + strMsg);
	}
	
	static {
		System.out.println("子类静态初始化器");
		System.out.println("子类成员变量=" + strMsg);
	}
	
	public void say() {
		System.out.println("子类说点什么,子类还是父类=" + strMsg);
	}
}


 

package com.javaeye.aspnetdb;
/**
 * 
 * @author aspnetdb 周洋
 * 测试的主类
 */
public class ClassOrderMain {

	public static void main(String[] args) {
		
		OrderSon son = new OrderSon();
		son.say();
		System.out.println("分咯线*****************************我咯咯咯");
		
		OrderFather father = new OrderFather();
		father.say();
		System.out.println("分格线*****************************我格格格");
		
		OrderFather father_son = new OrderSon();
		father_son.say();
		
	}

}

 

测试结果:

父类静态初始化器
父类成员变量=父类Msg
子类静态初始化器
子类成员变量=子类Msg
父类的构造函数
父类构造函数中,父类成员变量=父类Msg
子类构造函数
构造函数中,子类类成员变量=子类Msg
子类说点什么,子类还是父类=子类Msg
分咯线*****************************我咯咯咯
父类的构造函数
父类构造函数中,父类成员变量=父类Msg
父类说点什么,子类还是父类=父类Msg
分格线*****************************我格格格
父类的构造函数
父类构造函数中,父类成员变量=父类Msg
子类构造函数
构造函数中,子类类成员变量=子类Msg
子类说点什么,子类还是父类=子类Msg

 

可以看到,无论是父类还是子类,静态初始化器只执行一次,且父类的初始化器优先于子类的初始化器执行。

如果大家够仔细,debug一下,就可以看到父类还是子类,都是按照如下顺序来执行的。

初始化成员变量->执行初始化器->执行构造函数

 

第三个例子中,我顺便也测试了一下函数覆盖的问题。

可以看到,申请了子类大小的空间,调用从父类那里继承的方法,最后还是会访问实际申请出来的那个对象的方法。

方法中访问的成员变量也是实际申请出来的对象的变量。

 

注意:这篇博客只是做一个简单的测试,至于为什么是这个结果,我记得《Thinking in Java》中有写到过。以后如果有空,会不上原因分析的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics