今天,测试了一下java中成员变量、构造方法、代码块等的执行顺序,代码如下:
package com.carol.entity;
/**
* @author Carol Tang
* @version 1.0.0
* @date 2018-09-13 10:37
* @description 测试java中各代码的执行顺序
**/
class G_Member{
G_Member(){
System.out.println("[初始化G_Member实例成员变量]");
}
}
class G_StaticMember{
G_StaticMember(){
System.out.println("[初始化G_StaticMember静态成员变量]");
}
}
class F_Member{
F_Member(){
System.out.println("[初始化F_Member实例成员变量]");
}
}
class F_StaticMember{
F_StaticMember(){
System.out.println("[初始化F_StaticMember静态成员变量]");
}
}
class Grantfather {
//静态成员变量g_staticMember
static G_StaticMember g_staticMember = new G_StaticMember();
//实例成员变量g_member
G_Member g_member = new G_Member();
//静态成员变量name
public static String name = "grantfather";
//实例成员变量age
public int age = 18;
static {
System.out.println("Grantfather类,static静态代码块");
}
{
System.out.println("Grantfather类,构造代码块");
}
Grantfather() {
System.out.println("Grantfather类,无参构造方法,name = "+ name);
}
Grantfather(String name){
this.name = name; //如果没有将传入的参数赋值给本类的name,则默认输出是传入的参数值,而非本类静态name值
System.out.println("Grantfather类,有参构造方法,name = "+name);
}
Grantfather(int age){
System.out.println("Grantfather类,有参构造方法,age = "+age);//默认输出是传入的参数值,而非本类age
}
}
class Father extends Grantfather{
public String name = "father";
//静态成员变量 f_staticMember
static F_StaticMember f_staticMember = new F_StaticMember();
//实例成员变量f_member
F_Member f_member = new F_Member();
static {
System.out.println("Father类,static静态代码块");
}
{
System.out.println("Father类,构造代码块");
}
Father(){
// super();
// super.name = "txx";
super("txx");
//super(20);
System.out.println("Father类,无参构造方法,name = "+name);
}
Father(int age){
super();
super.age = age;//此处将修改Grantfather类的age,则Father类的age也改变
System.out.println("Father类,有参构造方法,name = "+name);
System.out.println("Father类,有参构造方法,age = "+age);
}
}
class Son extends Father{
Son(){
super();
System.out.println("Son类,无参构造方法");
System.out.println("Son类,name = "+name);
System.out.println("Son类,age = "+age);
}
}
public class Test{
public static void main(String[] args){
System.out.println("=======================第 1 次开始执行==================================");
Grantfather grantfather = new Grantfather();
System.out.println("=======================第 2 次开始执行==================================");
Grantfather grantfather2 = new Grantfather();
System.out.println("=======================第 3 次开始执行==================================");
Grantfather grantfather3 = new Grantfather("carol");
System.out.println("=======================第 4 次开始执行==================================");
Grantfather grantfather4 = new Grantfather(20);
System.out.println("Grantfather类,age = "+grantfather4.age);
System.out.println("Grantfather类,name = "+grantfather4.name);
System.out.println("=======================第 5 次开始执行==================================");
Father father = new Father();
System.out.println("=======================第 6 次开始执行==================================");
Father father2 = new Father(99);
System.out.println("Father类,age = "+father2.age);
System.out.println("=======================第 7 次开始执行==================================");
Son son = new Son();
System.out.println("========================第 8 次开始执行=================================");
Grantfather grantfather5 = new Grantfather();
System.out.println("Grantfather类,name = "+grantfather5.name);
}
}
输出结果如下:
=======================第 1 次开始执行==================================
[初始化G_StaticMember静态成员变量]
Grantfather类,static静态代码块
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = grantfather
=======================第 2 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = grantfather
=======================第 3 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = carol
=======================第 4 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,age = 20
Grantfather类,age = 18
Grantfather类,name = carol
=======================第 5 次开始执行==================================
[初始化F_StaticMember静态成员变量]
Father类,static静态代码块
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,无参构造方法,name = father
=======================第 6 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,有参构造方法,name = father
Father类,有参构造方法,age = 99
Father类,age = 99
=======================第 7 次开始执行==================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,有参构造方法,name = txx
[初始化F_Member实例成员变量]
Father类,构造代码块
Father类,无参构造方法,name = father
Son类,无参构造方法
Son类,name = father
Son类,age = 18
Son类,name = father
Son类,age = 18
========================第 8 次开始执行=================================
[初始化G_Member实例成员变量]
Grantfather类,构造代码块
Grantfather类,无参构造方法,name = txx
Grantfather类,name = txx
说明:
一般的类里面包含:
1、静态代码块(静态区、静态变量等)
2、构造代码块({ }中间的内容)
3、成员变量(静态成员变量、实例成员变量)
4、构造方法(有参构造方法、无参构造方法)
总结:
一般类中代码执行顺序如下:(“>” 表示优先于)
- 静态成员变量 > 实例成员变量 > 构造代码块 > 构造方法 ;
- 静态代码块 > 构造代码块 > 构造方法;
- 静态成员变量和静态代码块在类初始化阶段被初始化,且只初始化一次,两者顺序按照代码从上到下执行;
需要注意的是:
静态成员变量由于只被初始化一次,后续一旦被修改的,再实例化对象时,静态成员变量的值会是修改后的值,因此要慎用!
一般一次定义后永不再修改的变量,可声明为静态成员变量。
考虑到继承的特性,子类与父类的执行顺序是:
- 静态代码块(父) > 静态代码块(子) > 实例成员变量(父) > 构造代码块(父) > 构造方法(父) > 实例成员变量(子) > 构造代码块(子) > 构造方法(子)
扩展:
在子类中使用super(),默认调用的是父类的无参构造函数;
使用有参构造方法时,需注意如果方法里没有如:this.age = age ,则此类的成员变量age的值将不会被改变。
参考链接:https://baijiahao.baidu.com/s?id=1588663308864677376&wfr=spider&for=pc