我们在java中会遇到静态代码块、构造带码块、构造函数在一起出现的情况;或是具有继承关系中出现这种情况,这些代码块的执行顺序是什么呢,下面我会用一些示例来说明!
一、没有继承关系的情况
- 1.在非主类中,即非public类,出现构造代码块、静态代码块、构造函数的执行顺序:
//这是主类,即是public类;而在非主类即TestOrder中出现构造代码块、静态代码块、构造函数的执行次序;静态的代码块执行一次,没有main方法优先执行,main方法在主类中,所以先加载主类
public class CodeEexcuteOrder2 {
public static void main(String[] args) {
System.out.println("-----------main开始-------------");
// 测试创建多个TestOrder对象,随着对象的创建而执行构造代码块
TestOrder t1=new TestOrder();
TestOrder t2=new TestOrder();
TestOrder t3=new TestOrder();
System.out.println("-----------main结束-------------");
}
}
//非主类中,即非public类,构造代码块、静态代码块、构造函数的执行次序;静态的代码块执行一次
class TestOrder{
//我们从运行结果可以看出,构造代码块的执行次序优先于构造函数
public TestOrder() {
System.out.println("TestOrder的构造函数");
}
{
//这是构造代码块,指的是在一个类中的代码块
System.out.println("TestOrder类的构造代码块");
}
//静态代码块,只执行一次,不论创建出几个对象
static {
System.out.println("TestOrder静态的代码块");
}
}
执行结果
- 2.在public类,即是主类中构造代码块、静态代码块、构造函数的执行顺序:
/*
* 关于public类中构造代码块、构造函数、静态代码块的执行顺序;在主类中定义的静态块,优先于主方法(main)执行!,在JVM启动时执行
*/
public class CodeEexcuteOrder3 {
public CodeEexcuteOrder3() {
System.out.println("CodeEexcuteOrder3构造函数");
}
// 构造代码块,在类中出现的,出现次数与构造函数调用次数一样,然后执行优先于构造函数
{
System.out.println("CodeEexcuteOrder3中的构造代码块");
}
//最先执行,执行一次
static {
System.out.println("CodeEexcuteOrder3静态代码块");
}
public static void main(String[] args) {
System.out.println("---------main方法的开始---------");
//创建一个CodeEexcuteOrder3对象
CodeEexcuteOrder3 co1=new CodeEexcuteOrder3();
//创建第二个
CodeEexcuteOrder3 co2=new CodeEexcuteOrder3();
//创建第三个
CodeEexcuteOrder3 co3=new CodeEexcuteOrder3();
System.out.println("---------main方法的结束---------");
}
}
执行结果
在主类中即是public类(一个class文件中只能有一个,且首字母大写与类名一致)定义的静态代码块优先于main方法的执行
//在主类中定义的静态块,优先于主方法(main)执行!,在JVM启动时执行
//当编译执行时JVM会首先加载主类(即是public类),此时主类中的静态代码块就被执行。
public class CodeEexcuteOrder4 {
//主类中的,静态代码块、构造代码块、构造函数执行顺序
//构造函数
public CodeEexcuteOrder4() {
System.out.println("CodeEexcuteOrder4类的构造函数");
}
//静态代码块
static {
System.out.println("CodeEexcuteOrder4类的静态代码块");
}
//构造代码块它的执行随着CodeEexcuteOrder4类对象的创建而执行,创建几个对象则执行几次
{
System.out.println("CodeEexcuteOrder4类的构造代码块");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("-----------------main开始-----------------------------");
new CodeEexcuteOrder4();
System.out.println("-----------------main结束-----------------------------");
}
}
/*public class KFC{
}The public type KFC must be defined in its own file
,这个主类只能有一个,而且是定义这个类的文件名字一致
*
*/
运行结果
二、具有继承关系的情况,父类优先于子类,有爸爸了才能有儿子
package ExecuteOrder;
//具有继承关系的类之间,构造方法、静态代码块、构造代码的执行顺序
/*
* 执行结果,我们可以看出,main方法在public class Test1加载时就执行了,优先于static的执行
* ----------Test1类的main开始----------
父类的静态代码块
子类的静态代码块
父类的构造代码块
父类的构造方法
子类的构造代码块
子类的构造方法
----------Test1类的main结束---------
*/
public class Test1 {
public static void main(String[] args) {
// 这是测试类的main方法
System.out.println("----------Test1类的main开始----------");
//创建子类对象1,构造代码块的执行随着对象的创建出来而执行
Son s1=new Son();
// Son s2=new Son();
System.out.println("----------Test1类的main结束---------");
}
}
//父类
class Father{
//父类的构造函数
public Father() {
System.out.println("父类的构造方法");
}
//父类的构造代码块
{
System.out.println("父类的构造代码块");
}
//父类的静态代码块
static {
System.out.println("父类的静态代码块");
}
}
//子类
class Son extends Father{
//子类的构造函数
public Son() {
System.out.println("子类的构造方法");
}
//子类的构造代码块
{
System.out.println("子类的构造代码块");
}
//子类的静态代码块
static {
System.out.println("子类的静态代码块");
}
}
执行结果