反编译中的 匿名内部类 this.val$的问题

Posted libin6505

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反编译中的 匿名内部类 this.val$的问题相关的知识,希望对你有一定的参考价值。

转:

 

  一天偶尔在网上找到一个jar包,反编译后出现了如下的代码:

public void defineAnonymousInnerClass(String name)
 
    new Thread(name)   //extra constructor argument "name"
      public void run()
        System.out.println(this.val$name); //"this.val$"  is extra
     
   
    .start();
 

  当看到红色的部分时,我就纠结了。这是什么东西还能这么使用?后来在百度上搜索答案,却始终不得答案。最终在google找到了答案。

      链接地址:http://www.mindfiresolutions.com/A-tip-on-val$-field-in-Java-decompiled-code-1725.php

   其实,我是被编译器给玩了。这些代码都是编译器反编译的时候自己添加上去的。

  第一个问题:匿名内部类要使用外面的参数,必须要加final。而代码中却没有加。

  第二个问题:new Thread 这个类没有带参数的构造器。

  第三个问题:this.val$这种用法很怪异,val$是哪里来的。

  这些问题都是反编译器给我们搞的鬼。

  我们在学习匿名内部类的时候都知道,匿名内部类要使用外部的变量,或者参数,这个变量和参数都必须是final类型。而且匿名内部类没有构造器他的构造器是继承于父类,这就还有一个问题就是那我们如何初始化内名内部类中的变量,只需要使用“”在里面初始化变量不需要任何修饰。再就是在匿名内部类中this表示当前对象,如果要使用外部类对象需要加上Outclass.this这才是外部对象。

  所以以上代码我们做如下修改:

public void defineAnonymousInnerClass(final String name)//参数加上final
 
    new Thread()   //额外的参数去掉
      public void run()
        System.out.println(name); //"this.val$"  多余的去掉
     
   
    .start();
 

  这时我们就可以正常运行了,其实都是编译器搞的鬼。

  这是我第一次写博客,如有写的不对的地方请各位大侠们指教。

以上是关于反编译中的 匿名内部类 this.val$的问题的主要内容,如果未能解决你的问题,请参考以下文章

匿名内部类

ThinkingInJava第十章内部类

内部类和匿名内部类

什么是透明匿名高匿代理?详解!

匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型

为什么匿名内部类参数必须为final类型