终于搞懂了--静态代码块、构造代码块、构造函数的执行顺序
(1)静态代码块、构造代码块的定义区别:
//静态代码块 static{ System.out.println("静态代码块"); } //构造代码块.使用{}声明的代码块(和静态代码块的区别是少了static关键字): { System.out.println("构造代码块"); }
(2)示例1:静态代码块、构造代码块、构造函数、普通代码块的执行顺序
public class CodeBlock { static{ System.out.println("静态代码块"); } { System.out.println("构造代码块"); } public CodeBlock(){ System.out.println("无参构造函数"); } public void sayHello(){ { System.out.println("普通代码块"); } } public static void main(String[] args) { System.out.println("执行了main方法"); new CodeBlock().sayHello();; System.out.println("---------------"); new CodeBlock().sayHello();; } }
静态代码块 执行了main方法 构造代码块 无参构造函数 普通代码块 --------------- 构造代码块 无参构造函数 普通代码块
解析:
-
静态代码块最先执行,且先于static 的main方法执行
-
创建了两个匿名对象,但是静态代码块只是调用了一次。
-
每次创建对象的时候都会提前调用一次构造代码块
-
构造代码块在构造函数之前执行
(3)示例2:构造代码块、构造函数的执行顺序
public class CodeBlock { public void sayHello(){ { System.out.println("普通代码块"); } } public CodeBlock(){ System.out.println("无参构造函数"); } { System.out.println("构造代码块"); } static{ System.out.println("静态代码块"); } public static void main(String[] args) { System.out.println("执行了main方法"); new CodeBlock().sayHello();; System.out.println("---------------"); new CodeBlock().sayHello();; } }
静态代码块 执行了main方法 构造代码块 无参构造函数 普通代码块 --------------- 构造代码块 无参构造函数 普通代码块
解析:验证了构造代码块优先于构造函数执行,与定义顺序无关
(4) 示例3::构造代码块的作用
public class Demo01 { public static void main(String[] args) { Test test = new Test(3); //构造代码块会在构造函数被调用时执行, 且在这个例子中比"this.id=id;"语句先执行,作用是给对象统一初始化数据; System.out.println(test); } } class Test{ int id; String name; { this.id= 5; System.out.println(this.id); this.name = "测试"; System.out.println("这是构造代码块"); } Test(int id){ this.id = id; } public String toString(){ return "name: "+this.name +","+"id: "+ this.id ;//这里的name没有在构造函数中赋值,但是却有值,因为构造代码块已经初始化过了 } }
5
这是构造代码块
name: 测试 , id: 3
如果把下面这一段注释掉:name就没有被初始化,只有默认值null
{ this.id= 5; System.out.println(this.id); //this.name = "测试"; System.out.println("这是构造代码块"); }
5 这是构造代码块 name: null,id: 3
解析:
-
构造代码块的作用是给构造函数初始化
-
构造代码块要优先于构造函数执行
(5)总结:
构造代码块、静态代码块的定义不同
静态代码块的作用是给类初始化
构造代码块的作用是给构造函数初始化