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》中有写到过。以后如果有空,会不上原因分析的。
分享到:
相关推荐
java 使用类作为成员变量 java 使用类作为成员变量
75.java成员变量与局部变量.zip75.java成员变量与局部变量.zip75.java成员变量与局部变量.zip75.java成员变量与局部变量.zip75.java成员变量与局部变量.zip75.java成员变量与局部变量.zip75.java成员变量与局部变量....
Java 面向对象中的两类 变量 : 成员变量和局部变量
Java中的变量的详细介绍 。介绍成员变量和局部变量的区别。成员变量中的实例变量和静态变量的区变。
1、写一个判断素数的过程。以整数作为参数,若为素数则输出True,否则输出False 2、 写两个函数,分别求两个数的最大公约数和最小公倍数 3、 编写一个过程,用来计算并输出: 4、 Fibonacci数列的第一项是0,第二项...
C++,C 包含类两个类互相调用彼此的类成员变量和方法,里面介绍了如何在头文件中创建相互的类对象,简单易懂
java 利用反射获取内部类静态成员变量的值操作.docx
statilocal java 静态变量和静态块加载顺序,静态变量和同名静态变量块加载的顺序。
详细介绍了Java的静态成员变量、静态数据块、非静态成员变量和非静态成员变量等初始化顺序
详细了解成员变量的覆盖问题,代码详细介绍,还有注释,易懂
题目:建立一个名为Student的类,该类有以下几个私有成员变量:学生姓名、学号、性别、年龄。还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个...
Java成员变量类变量局部变量的区别共5页.pdf.zip
Java类变量和方法, 介绍了java中类变量和方法
Java 关键字修饰成员变量例子。
定义一个Document类,包含成员变量name,从Document派生出Book类,增加PageCount变量。编写主函数测试这两个类
① 圆类Circle的成员变量:radius表示圆的半径。 ② 圆类Circle的方法成员: Circle():构造方法,将半径置0 Circle(double r):构造方法,创建Circle对象时将半径初始化为r double getArea():获得圆...
题目:建立一个名为Student的类,该类有以下几个私有成员变量:学生姓名、学号、性别、年龄。还有以下两个成员函数:一个用于初始化学生姓名、学号、性别和年龄的构造函数,一个用于输出学生信息的函数。编写一个...