局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?

局部内部类为什么只能访问final局部变量,对于成员变量却可以随便访问?

Java代码   收藏代码
  1. public class OuterClass {  
  2.     private int memberField = 10;  
  3.       
  4.     public void outerDo(){  
  5.         final int localField = fromOther();  
  6.           
  7.         class InnerClass{  
  8.             public void innerDo(){  
  9.                 memberField = localField;  
  10.             }  
  11.         };  
  12.     }  
  13.   
  14.     private int fromOther() {  
  15.         return 20;  
  16.     }  
  17. }  
 

局部变量和成员变量对于内部类而言,具有一定的共性,都是该内部类外面的变量。如果要求内部类只能访问final的局部变量是为了确保局部变量不被修改的话,那么内部类访问成员变量应该也有类似的限制才对

 

 

我认为是由于他们的存活范围导致了这个区别:

首先内部类的实例可以在方法结束后依然存活,局部变量在方法结束后却无法存活,所以在内部类中无法访问NON-final的局部变量;

而成员变量的存活时间是取决于外部类的实例的,内部类实例中都会引用当前外部类实例,所以他们拥有一致的生命周期,于是可以访问成员变量。

 

剩下的问题是,为什么可以访问final的局部变量呢?

如果将一个访问了final的局部变量的内部类进行反编译,可以发现该变量是被作为构造函数的参数传入进去的,与之一起传入的参数还有外部类实例

......

扫描二维码关注公众号,回复: 4057317 查看本文章

com.study.innerclass.OuterClass$1InnerClass(com.study.innerclass.OuterClass, int);
  Code:
   Stack=2, Locals=3, Args_size=3
   0:    aload_0
   1:    aload_1
   2:    putfield    #12; //Field this$0:Lcom/study/innerclass/OuterClass;
   5:    aload_0
   6:    iload_2
   7:    putfield    #14; //Field val$localField:I
   10:    aload_0
   11:    invokespecial    #16; //Method java/lang/Object."<init>":()V
   14:    return
  LineNumberTable: 
   line 9: 0

  LocalVariableTable: 
   Start  Length  Slot  Name   Signature
   0      15      0    this       Lcom/study/innerclass/OuterClass$1InnerClass;

 

 

既然javac是这样处理内部类的,那么这与为内部类提供一个带参数的构造函数就没什么两样了!

Java代码   收藏代码
  1. public class OuterClass {  
  2.     private int memberField = 10;  
  3.       
  4.     public void outerDo(){  
  5.         int localField = fromOther();  
  6.           
  7.         class InnerClass{  
  8.             private int local;  
  9.             public InnerClass(int local) {  
  10.                 this.local = local;  
  11.             }  
  12.             public void innerDo(){  
  13.                 memberField = this.local;  
  14.             }  
  15.         };  
  16.         new InnerClass(localField);  
  17.     }  
  18.   
  19.     private int fromOther() {  
  20.         return 20;  
  21.     }  
  22. }  

猜你喜欢

转载自blog.csdn.net/dylan2183/article/details/52771020