博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
final 语义
阅读量:6617 次
发布时间:2019-06-25

本文共 3194 字,大约阅读时间需要 10 分钟。

我们都知道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             @Override12             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             @Override25             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             @Override36             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内存屏障语义。

 

转载于:https://www.cnblogs.com/hf-china/p/9578690.html

你可能感兴趣的文章
java封装httpClient工具(支持http和https,包含get和post请求)
查看>>
Rocket - diplomacy - LazyModuleImpLike
查看>>
如何取消OneNote的粘贴来源地址
查看>>
Nginx+Tomcat实现动静分离
查看>>
Exchange Server 2016管理系列课件25.管理安全通讯组
查看>>
计算机科学,大一学生怎样来爱你(文&PPT)
查看>>
linux中vmstat命令详解
查看>>
PHP 开发社区微信服务号实战图解
查看>>
Exchange Server 2013 系列八:邮箱服务器角色DAG实战
查看>>
php使用curl下载指定大小的文件
查看>>
VS2013创建Node.js C++ Addons的过程
查看>>
amaze ui中的icon button
查看>>
tcp 三次握手
查看>>
XML中添加换行符
查看>>
在C#中使用属性控件添加属性窗口
查看>>
printf()详解之终极无惑
查看>>
交叉检验---训练数据,验证数据和测试数据
查看>>
AspNetPager分页控件配置
查看>>
第 8 章 Spring Data
查看>>
[裴礼文数学分析中的典型问题与方法习题参考解答]5.1.24
查看>>