• final 语义


    我们都知道final修饰的成员是不可变。下面分析final在内部类的语义特征。

    首先看一个简单的例子。

     1 public class FinalExample {
     2 
     3 
     4     private String fis = "final-init";
     5 
     6     public void method1() {
     7 
     8         final String key = "key1";
     9 
    10         new Thread(new Runnable() {
    11             @Override
    12             public void run() {
    13                 System.out.println(key);
    14                 System.out.println(fis);
    15             }
    16         });
    17 
    18     }
    19 
    20     public void method2() {
    21         final String key = new String("key1");
    22 
    23         new Thread(new Runnable() {
    24             @Override
    25             public void run() {
    26                 System.out.println(key);
    27                 System.out.println(fis);
    28             }
    29         });
    30     }
    31 
    32     public void method3(final String key) {
    33 
    34         new Thread(new Runnable() {
    35             @Override
    36             public void run() {
    37                 System.out.println(key);
    38                 System.out.println(fis);
    39             }
    40         });
    41     }
    42 
    43 }
    View Code

    编译器生成的代码:

    FinalExample类:

     1 public class FinalExample {
     2     private String fis = "final-init";
     3 
     4     public FinalExample() {
     5     }
     6 
     7     public void method1() {
     8         String key = "key1";
     9         new Thread(new Runnable() {
    10             public void run() {
    11                 System.out.println("key1");
    12                 System.out.println(FinalExample.this.fis);
    13             }
    14         });
    15     }
    16 
    17     public void method2() {
    18         final String key = new String("key1");
    19         new Thread(new Runnable() {
    20             public void run() {
    21                 System.out.println(key);
    22                 System.out.println(FinalExample.this.fis);
    23             }
    24         });
    25     }
    26 
    27     public void method3(final String key) {
    28         new Thread(new Runnable() {
    29             public void run() {
    30                 System.out.println(key);
    31                 System.out.println(FinalExample.this.fis);
    32             }
    33         });
    34     }
    35 }
    View Code

    方法1的内部类:

     1 class FinalExample$1 implements Runnable {
     2     FinalExample$1(FinalExample var1) {
     3         this.this$0 = var1;
     4     }
     5 
     6     public void run() {
     7         System.out.println("key1");
     8         System.out.println(FinalExample.access$000(this.this$0));
     9     }
    10 }
    View Code

    方法2的内部类:

     1 class FinalExample$2 implements Runnable {
     2     FinalExample$2(FinalExample var1, String var2) {
     3         this.this$0 = var1;
     4         this.val$key = var2;
     5     }
     6 
     7     public void run() {
     8         System.out.println(this.val$key);
     9         System.out.println(FinalExample.access$000(this.this$0));
    10     }
    11 }
    View Code

    方法3的内部类:

     1 class FinalExample$3 implements Runnable {
     2     FinalExample$3(FinalExample var1, String var2) {
     3         this.this$0 = var1;
     4         this.val$key = var2;
     5     }
     6 
     7     public void run() {
     8         System.out.println(this.val$key);
     9         System.out.println(FinalExample.access$000(this.this$0));
    10     }
    11 }
    View Code

    以上可以看出,final修饰的局部变量。如果是引用类型的变量,内部类会生成一个有参构造方法,将此变量传入构造函数。然后通过外部类中的access$*()方法获取到外部类中的值(该方法是通过编译器生成的)。 如果是基本类型,值直接编译到class文件。

    通过汇编指令,反编译暂未发现网上说的final内存屏障语义。

  • 相关阅读:
    (转)详谈高端内存和低端内存
    高级声明------定义一个函数指针数组指针
    A Bug's Life POJ
    How Many Answers Are Wrong HDU
    A
    B
    数据处理----离散化
    Serval and Parenthesis Sequence CodeForces
    D
    C
  • 原文地址:https://www.cnblogs.com/hf-china/p/9578690.html
Copyright © 2020-2023  润新知