A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 曹英 中级黑马   /  2013-3-24 23:34  /  1804 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 曹英 于 2013-3-26 00:07 编辑

为什么内部类只能访问final修饰的局部变量

点评

记得及时处理帖子哦,继续追问,或将分类改成【已解决】,谢谢  发表于 2013-3-25 19:17

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

4 个回复

倒序浏览
这个说起来就比较复杂了.总的来说是内部类和外部类的局部变量的生命周期不同导致的.
内部类的对象可以再方法结束后继续存活(只要改对象被引用了就不会消亡),但是方法结束了,局部变量却消亡了.这就会出现内部类的对象去调用一个不存在的局部变量这种奇怪的事情.
那为毛用final修饰以后就可以了呢?
这一点我还没有完全理解,网上的解释是这样的.
定义为final后,编译程序的实现方法:将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。
希望对卤煮有帮助.

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
这个问题,跟内存有关,局部变量存在于栈中,用完立即就消失了,当程序运行到内部类时,这个局部变量已经消失,显然行不通,而final的功能可以让它所修饰的变量变成常量,生命周期远高于局部变量,就不会出现访问不到的情况了,下面附代码。
  1. class Outer {
  2.         public void aaa(){
  3.                         //final修饰的变量a
  4.             final int a =10;
  5.                         //内部类
  6.             class Inner{
  7.                 public void seeOuter(){
  8.                                         //访问a
  9.                     System.out.println(a);
  10.                 }
  11.             }   
  12.             Inner in = new Inner();
  13.             in.seeOuter();
  14.         }
  15.         public static void main(String[] args) {
  16.             Outer out = new Outer();
  17.             out.aaa();
  18.         }
  19.      }
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
我们先来看下面的程序:
class Outer{
        public void function(){
                final int num=9;
                class Inner{
                        public void show(){
                                System.out.println(num);
                        }
                }
                Inner in=new Inner();
                in.show();
        }
}
public class Test{
        public static void main(String[] args){
                new Outer().function();
        }
}
这是一个内部类,当内部类在局部位置上只能访问具备中被final修饰的局部变量,此时的变量就成为常量。
为什么呢?
理由:我们知道方法的局部变量位于栈上,只存在于该方法的生命期内。当一个function的方法结束,就会弹栈
局部变量就会消失。但是该方法结束之后,在方法内创建的内部类对象(用new创建的对象in)可能仍然存在于堆中!
例如,此时,如果我们对该对象进行引用,那么此时,show方法中的num就不存在,这时候,就会产生错误。因为
new的对象和num的生命周期不一样长。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
将某个类的整体定义为final 时,该类无法被继承。而且由于final类禁止继承,所以final类中所有的方法都隐式指定为final的,因为无法覆盖它们。
final 用于类或方法是为了防止方法间的链接被破坏。例如,假定类 X 的某个方法的实现假设了方法 M 将以某种方式工作。将 X 或 M 声明成 final 将防止派生类以这种方式重新定义 M,从而导致 X 的工作不正常。尽管不用这些内部相关性来实现 X 可能会更好,但这不总是可行的,而且使用 final 可以防止今后这类不兼容的更改。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马