24 08 2020

Java 中的代码块

1. 普通代码块

方法中的代码块。

2. 构造代码块

构造块会在创建对象时被调用,每次创建都会被调用,优先于类构造函数执行。

3. 静态代码块

用 static{} 包裹起来的代码片段,只会执行一次。静态代码块优先于构造代码块执行。

4. 同步代码块

使用 synchronized(){} 包裹起来的代码块,在多线程环境下,对共享数据的读写操作是需要互斥进行的,否则会导致数据的不一致性。同步代码块需要写在方法中。

代码块的执行顺序

1.继承的代码执行顺序

示例代码:

  1. public class Test1 {
  2. public static void main(String[] args) {
  3. B b1 = new B();
  4. System.out.println("再new一个");
  5. B b2 = new B();
  6. }
  7. }
  8. class A {
  9. static {
  10. System.out.println("class A static block ");
  11. }
  12. {
  13. System.out.println("class A regular block ");
  14. }
  15. public A() {
  16. System.out.println("class A constructor block ");
  17. }
  18. }
  19. class B extends A {
  20. static {
  21. System.out.println("class B static block ");
  22. }
  23. {
  24. System.out.println("class B regular block ");
  25. }
  26. public B() {
  27. System.out.println("class B constructor block ");
  28. }
  29. }

运行结果:

  1. class A static block
  2. class B static block
  3. class A regular block
  4. class A constructor block
  5. class B regular block
  6. class B constructor block
  7. new一个
  8. class A regular block
  9. class A constructor block
  10. class B regular block
  11. class B constructor block

结论:

  1. 1.父类中的静态代码块 1
  2. 2.子类中的静态代码块 1
  3. 3.父类中的构造代码块 new一次都执行
  4. 4.父类中的构造方法 new一次都执行
  5. 5.子类中的构造代码块 new一次都执行
  6. 6.子类中的构造方法 new一次都执行
2.内部类的代码执行顺序

示例代码:

  1. public class Test2 {
  2. public static void main(String[] args) {
  3. //分别单独运行以下3条
  4. OuterClass outerClass=new OuterClass();
  5. OuterClass.StaticInnerClass staticInnerClass=new OuterClass.StaticInnerClass();
  6. OuterClass.InnerClass innerClass=new OuterClass().new InnerClass();
  7. }
  8. }
  9. class OuterClass {
  10. static {
  11. System.out.println("class OuterClass static block ");
  12. }
  13. {
  14. System.out.println("class OuterClass regular block ");
  15. }
  16. public OuterClass() {
  17. System.out.println("class OuterClass constructor block ");
  18. }
  19. static class StaticInnerClass {
  20. static {
  21. System.out.println("class StaticInnerClass static block ");
  22. }
  23. {
  24. System.out.println("class StaticInnerClass regular block ");
  25. }
  26. public StaticInnerClass() {
  27. System.out.println("class StaticInnerClass constructor block ");
  28. }
  29. }
  30. class InnerClass {
  31. {
  32. System.out.println("class InnerClass regular block ");
  33. }
  34. public InnerClass() {
  35. System.out.println("class InnerClass constructor block ");
  36. }
  37. }
  38. }

OuterClass outerClass=new OuterClass(); 运行结果:

  1. class OuterClass static block
  2. class OuterClass regular block
  3. class OuterClass constructor block

OuterClass.StaticInnerClass staticInnerClass=new OuterClass.StaticInnerClass();运行结果:

  1. class StaticInnerClass static block
  2. class StaticInnerClass regular block
  3. class StaticInnerClass constructor block

OuterClass.InnerClass innerClass=new OuterClass().new InnerClass();运行结果:

  1. class OuterClass static block
  2. class OuterClass regular block
  3. class OuterClass constructor block
  4. class InnerClass regular block
  5. class InnerClass constructor block

结论:

  1. 1.静态内部类中才允许使用静态代码块
  2. 2.内部类编译之后,会形成独立的.class文件
  3. 3.仅仅实例化外部类对象时,仅仅将外部类加载进内存,内部类暂时不加载
  4. 4.在实例化静态内部类对象时,仅仅执行内部类的代码块,外部类代码块不执行
  5. 5.在实例化非静态内部类对象时,先把外部类的代码块和构造器执行完毕后再执行内部类的代码块和构造器
延伸阅读
  1. Java 代码块及代码块和构造方法的执行顺序
  2. java8新特性有哪些
  3. 抽象类(abstract class)和接口(interface)有什么异同
  4. 位运算符:与(&)、非(~)、或(|)、异或(^)
  5. 【面试题】实现打印26个数字和26个字母交替打印
发表评论