目录
1.代码块的基本介绍
代码块又称为初始化块,属于类中的成员【即 是类的一部分】,类似于类的方法,将逻辑语句封装在方法体中,通过{}包围起来。
但和方法不同,代码块没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建类时隐式调用。
package com.fs; public class Test1 { public static void main(String[] args) { Read read = new Read("小红"); System.out.println("============="); Read read1 = new Read("小明"); } } class Read { private String name; { System.out.println("阅读时间到!"); } public Read(String name) { this.name = name; System.out.println(name + "正在看书"); } }
2.静态代码块的基本介绍
static代码块叫静态代码块,作用是对类进行初始化它随着类的加载进行初始化,而且随着类的加载而被执行并且只会执行一次。如果是普通代码块,每次创建一个对象就执行一次。
1.创建对象实例时
package com.fs; public class Test2 { public static void main(String[] args) { //1、创建对象实例时(new) new AAA(); } } class AAA{ static{ System.out.println("AAA的静态代码块被调用"); } }
2.创建子类对象实例时
package com.fs; public class Test3 { public static void main(String[] args) { //2、创建子类对象实例时,父类也会被加载,而且父类先被加载,子类后被加载 new BBB(); } } class BBB extends AAA{ static{ System.out.println("BBB的静态代码块被调用"); } }
3.使用类的静态成员时
package com.fs; public class Test4 { public static void main(String[] args) { //3、使用类的静态成员时(静态属性,静态方法) System.out.println(CCC.n); } } class CCC{ public static int n=99; static{ System.out.println("CCC的静态代码块被调用"); } }
3.两种代码块的使用细节
普通的代码块,会在创建对象实例时创建。每创建对象一次,就会调用一次。
静态的代码块,只在类加载时创建且只创建一次。
package com.fs; public class Test1 { public static void main(String[] args) { Read read = new Read("小红"); System.out.println("============="); Read read1 = new Read("小明"); } } class Read { private String name; { System.out.println("阅读时间到!"); } public Read(String name) { this.name = name; System.out.println(name + "正在看书"); } }
如果只是使用类的静态成员时,普通代码块并不会执行。
package com.fs; public class Test6 { public static void main(String[] args) { System.out.println(DDD.n); } }
4.创建对象时,在类中的被调用顺序
package com.fs; public class Test7 { public static void main(String[] args) { D d=new D(); } } class D{ public D() { System.out.println("D的无参构造器被调用"); } { System.out.println("普通代码块被调用"); } private int n2 = getn2(); private static int n1=getn1(); static{ System.out.println("D的静态代码块被调用"); } public static int getn1(){ System.out.println("getn1被调用"); return 100; } public int getn2(){ System.out.println("getn2被调用"); return 99; } }
1.先是静态代码块与静态成员。(静态代码块与静态成员的先后顺序由定义顺序决定)
2.然后是普通代码块与非静态成员。(普通代码块与非静态成员的先后顺序同样由定义顺序决定)
3.最后是构造方法。
5.存在继承时,在类中的被调用顺序
package com.fs; public class Test8 { public static void main(String[] args) { F f=new F(); } } class F extends E{ public F() { System.out.println("子类F的无参构造器被调用"); } { System.out.println("子类F的普通代码块被调用"); } private int n2 = getn2(); private static int n1=getn1(); static{ System.out.println("子类F的静态代码块被调用"); } public static int getn1(){ System.out.println("子类getn1被调用"); return 100; } public int getn2(){ System.out.println("子类getn2被调用"); return 99; } } class E{ public E() { System.out.println("父类E的无参构造器被调用"); } { System.out.println("父类E的普通代码块被调用"); } private int n2 = getn4(); private static int n1=getn3(); static{ System.out.println("父类E的静态代码块被调用"); } public static int getn3(){ System.out.println("父类的getn3被调用"); return 100; } public int getn4(){ System.out.println("父类的getn4被调用"); return 99; } }
1.父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
2.子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
3.父类的普通代码块和普通属性的初始化(优先级一样,按定义顺序执行)
4.父类的构造方法
5.子类的普通代码块和普通属性的初始化(优先级一样,按定义顺序执行)
6.子类的构造方法