The reason anonymous inner classes and inner classes can only access the local variables of final

The following are recruited from the major sites explain, I excerpt here from other places come to move some of the general idea, may be more chaotic,
detailed explanation
http://blog.csdn.net/salahg/article/details/7529091

3.1. The reasons of

The problem is the scope of variables, because anonymous inner class that appears inside a method, variable, if it is to access the parameters of this method or methods defined in these parameters and variables must be modified as final. Although due to internal anonymous inner classes in the process, the actual translation of the inner Outer.Inner compiled into class, which illustrates a method and a position located inside the outer class class are on the same level, the outer class method the local variables only variables or parameters of the method, the scope of these variables or parameters are valid only within this method.
This is a compiler design problem, and if you understand the java compiler theory it is easy to understand.
First, the internal class time will be compiled to generate a separate .class file within the class, and the file is not an external class file and class.
Because the compiler when the internal classes and methods at the same level, so the process variables or parameters only for the final, inner classes can reference.
When the parameter is passed outside the class is called inner classes, direct call from the point of view java program
e.g.

public void dosome(final String a,final int b){
class Dosome{public void dosome(){System.out.println(a+b)}};
  Dosome some=new Dosome();
          some.dosome();
          }

From the code point of view it seems to be a parameter and the parameter b inner class called directly, but not actually, after the java compiler to compile the actual operation code is

class Outer$Dosome{
    public Dosome(final String a,final int b){
        this.Dosome$a=a;
        this.Dosome$b=b;
    }
    public void dosome(){
        System.out.println(this.Dosome$a+this.Dosome$b);
    }
}
    }
     从以上代码看来,内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。  
    这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西,如果编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是final来规避这种莫名其妙错误的存在。
 (简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变)

3.2. Personal understanding

   (我对上面这段话的大致理解是这样的:虽然内部类是在外部类里面,但是在编译之后这是两个不同的class文件,而内部类在使用外部类的成员变量之后,却被编译成了两个不同的class文件,所以内部类中使用的那个从外部类传过来的那个变量实际并不是外部类中的变量,只是外部类变量的一个拷贝,这样就导致了即使内部类中修改了该变量的值,也不会让外部类中的那个变量发生任何改变,这样就导致一个情况,在同一个Java程序里面,同样名字的一个变量却同时产生了两个不同的值!这是非常荒唐的一件事情,就相当于a等于1的同时又等于2,失去了参数的一致性,所以为了避免这种问题,所以限定内部类可以使用的参数必须为final类型 因为当变量是final时,如果是基本数据类型,由于其值不变,因而:其复制品与原始的量是一样。语义效果相同.(若如果不是final,就无法保证:复制品与原始变量保持一致了,因为在方法中改的是原始变量,而局部内部类中改的是复制品),所以为了保证内部类和外部类中这两个变量值的一致性,所以就把内部类可以使用的外部类的变量限定成final,让内部类无法再修改使用的参数的值,从而避免出现a等于1的同时又等于2这种情况,保证了参数值的一致性)

Guess you like

Origin www.cnblogs.com/blackmlik/p/12077113.html