方法内部类/匿名内部类 局部变量需要被标记为final 原因

public class InnerClassTest {
	public int classLevel = 0;
	
	public void test(final long innerMethodParam){
		 final Integer methodLevel = new Integer(2);
		new MethodInnerClass(){
			public void innerMethod(){
				Integer a2 = methodLevel;
				int b = classLevel;
				long c = innerMethodParam;
			}};
	}
	class MethodInnerClass{}
}

匿名内部类的构造器部分字节码:

  InnerClassTest.InnerClassTest$1(InnerClassTest.InnerClassTest, InnerClassTest.InnerClassTest, java.lang.Integer, long);
    descriptor: (LInnerClassTest/InnerClassTest;LInnerClassTest/InnerClassTest;Ljava/lang/Integer;J)V
    flags:
    Code:
      stack=3, locals=6, args_size=5
         0: aload_0
         1: aload_2
         2: putfield      #14                 // Field this$0:LInnerClassTest/InnerClassTest;
         5: aload_0
         6: aload_3
         7: putfield      #16                 // Field val$methodLevel2:Ljava/lang/Integer;
        10: aload_0
        11: lload         4
        13: putfield      #18                 // Field val$innerMethodParam:J
        16: aload_0
        17: aload_1
        18: invokespecial #20                 // Method InnerClassTest/InnerClassTest$MethodInnerClass."<init>":(LInnerClassTest/InnerClassTest;)V
        21: return
      LineNumberTable:
        line 1: 0
        line 9: 16
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      22     0  this   LInnerClassTest/InnerClassTest$1;

1)该构造器传入了外部类的this,以及方法的局部变量和方法的输入参数。

2)java中都是值传递。


以上两个原因直接导致:

a. 内部类修改外部类的属性会直接修改,this.xxx。

b. 内部类修改方法的局部变量或者方法的输入参数时,根本改不到。


为了保证代码看起来符合逻辑,所以方法的局部变量或者方法的输入参数需要保证是final。

所以并不是什么生命周期的原因,主要还是为了让代码易懂。



猜你喜欢

转载自blog.csdn.net/u011385186/article/details/79051492