为什么匿名内部类和局部内部类只能访问final变量

是变量的作用域的问题,因为匿名内部类是出现在一个方法的内部的,如果它要访问这个方法的参数或者方法中定义的变量,则这些参数和变量必须被修饰为final。

一个xx.java类里面有匿名内部类,编译出来的class文件会有xx.class 、xx$1.calss...
例如:

public class InnerClass {

 public static void test(final String s){            
     InnerClass c = new InnerClass(){ 
         public void m(){ 
             int x = s.hashCode();   
             System.out.println(x);  
         } 
    };  
 }
}

编译出来的两个class文件是:InnerClass.class和 InnerClass$1.class,代码分别如下:

package smartpush;

import java.io.PrintStream;

public class InnerClass
{
  public static void test(String s)
  {
    InnerClass c = new InnerClass(s) {
      public void m() {
        int x = this.val$s.hashCode();
      System.out.println(x);
  }
 };
}
}

package smartpush;

import java.io.PrintStream;

class 1 extends InnerClass
{
  public void m()
{
  int x = this.val$s.hashCode();
  System.out.println(x);
}
}

这说明虽然匿名内部类在方法的内部,但实际编译的时候,内部类会编译成一个inner_object,而外部类中的方法中的变量s只是方法的局部变量,s的作用域只在这个方法内部有效。查看反编译出来的源码,内部类 class 1

int x = this.val$s.hashCode();

内部类使用this.val$s引用了方法内部的变量s

对于一个final变量:
如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

因此内部类要引用变量s,编译器就要保证s的引用 this.val$s在初始化后就不能再改变。
不然如果在内部类的方法执行前,s的引用指向了其他地方,例如
s="321"

这样匿名类的变量指向B而外部的变量却指向A了,这结果显然是不能接受的
于是为了保证变量引用的一致性,内部类只能访问final变量。

http://stackoverflow.com/questions/3910324/why-java-inner-classes-require-final-outer-instance-variables
http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen
http://feiyeguohai.iteye.com/blog/1500108
http://blog.csdn.net/woshichunchun/article/details/7925823
http://blog.csdn.net/axman/article/details/1460544

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,719评论 18 399
  • 本文首发于我的个人博客 —— Bridge for You,转载请标明出处。 前言 我们先来看一道很简单的小题: ...
    柳树之阅读 5,367评论 3 23
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 7,650评论 0 11
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 4,822评论 0 4
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 5,127评论 0 2

友情链接更多精彩内容