匿名内部类和局部内部类中只能访问final变量的原因
2018-01-02 22:31
671 查看
在一个方法中,如果创建一个匿名内部类,并且在内部类中药访问方法的参数,我们必须将该参数用final进行修饰才能访问,这个的原因主要是由于方法和内部类的生命周期不相同导致的。
当我们执行一个带参的方法时,在该方法的调用栈中将生成一个局部变量(即该参数),如果在该方法中创建了局部内部类,则jvm会产生一个inner_object,但是,此inner_object并不会随着方法的执行完毕而销毁。因此,当方法执行完毕之后,方法调用栈中的局部变量也将销毁,这个时候局部内部类没有被销毁,就会发生之前能访问的参数此时找不到了的尴尬情况。
而当我们使用final对参数进行修饰之后,jvm中将产生一个该参数的复制,局部内部类不再直接访问该参数,而是访问这个参数的复制。这样,当方法执行完毕,调用栈中的参数销毁之后,局部内部类依然可以访问到这个参数在jvm中的复制,而不会发生异常。
上述的限制在Java8中已经不复存在了,从Java8开始,我们不再需要将参数定义为final,局部内部类也可以正常的访问方法中的参数。
In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final. When a local class accesses a local variable or parameter of the enclosing block, it captures that
variable or parameter.
However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized
is effectively final.
Starting in Java SE 8, if you declare the local class in a method, it can access the method's parameters.
https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html#accessing-members-of-an-enclosing-class
参考:
当我们执行一个带参的方法时,在该方法的调用栈中将生成一个局部变量(即该参数),如果在该方法中创建了局部内部类,则jvm会产生一个inner_object,但是,此inner_object并不会随着方法的执行完毕而销毁。因此,当方法执行完毕之后,方法调用栈中的局部变量也将销毁,这个时候局部内部类没有被销毁,就会发生之前能访问的参数此时找不到了的尴尬情况。
而当我们使用final对参数进行修饰之后,jvm中将产生一个该参数的复制,局部内部类不再直接访问该参数,而是访问这个参数的复制。这样,当方法执行完毕,调用栈中的参数销毁之后,局部内部类依然可以访问到这个参数在jvm中的复制,而不会发生异常。
上述的限制在Java8中已经不复存在了,从Java8开始,我们不再需要将参数定义为final,局部内部类也可以正常的访问方法中的参数。
In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final. When a local class accesses a local variable or parameter of the enclosing block, it captures that
variable or parameter.
However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized
is effectively final.
Starting in Java SE 8, if you declare the local class in a method, it can access the method's parameters.
https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html#accessing-members-of-an-enclosing-class
参考:
为什么匿名内部类参数必须为final类型
上述文章中详细讲解了内部类访问方法参数这种看似天经地义的事情为什么要多此一举加个final修饰符的原因:“这个规定是一种无可奈何.也说明:程序设计语言的设计是受到实现技术的限制的”相关文章推荐
- 为什么匿名内部类和局部内部类只能访问final变量
- 注意java8中已经没有匿名内部类和局部内部类只能访问final变量的限制了!
- 为什么匿名内部类和局部内部类只能访问final变量
- 为什么匿名内部类和局部内部类只能访问final变量
- 为什么匿名内部类和局部内部类只能访问final变量
- 为什么匿名内部类和局部内部类只能访问final变量
- Java基础-内部类-为什么局部和匿名内部类只能访问局部final变量
- java学习记录(四):关于匿名内部类和局部内部类只能访问final变量的问题
- Java中为什么匿名内部类和局部内部类只能访问final变量?
- 为什么匿名内部类只能访问其所在方法中的final类型的局部变量?
- 为什么在方法中定义的内部类只能访问方法中的final类型的局部变量?
- 内部类只能访问final修饰局部变量
- 为什么局部内部类和匿名内部类只能访问final的局部变量?
- 局部内部类的成员变量被final修饰才能被局部内部类的方法所访问
- JAVA匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型
- 为什么在方法中定义的内部类只能访问方法中的final类型的局部变量?
- 局部内部类只能访问非final变量
- 【转自JavaEye】为什么“局部内部类能且只能访问所在方法中的final类型的参数和变量”?
- 为什么匿名内部类只能访问其所在方法中的final变量
- 为什么匿名内部类只能访问final变量【转】