黑马程序员技术交流社区

标题: 关不final [打印本页]

作者: 朱烈葵    时间: 2012-8-22 14:41
标题: 关不final
为什么内部类访问外部类的局部变量,该变量需要被final修饰?
作者: 李知伦    时间: 2012-8-22 15:12
在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。

这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。

因为虽然这种部类在方法的内部,但实际编译的时候,内部类编译成Outer.Inner,这说明内部类所处的位置和外部类中的方法处在同一个等级上,外部类中的方法中的变量或参数只是方法的局部变量,这些变量或参数的作用域只在这个方法内部有效。因为编译的时候内部类和方法在同一级别上,所以方法中的变量或参数只有为final,内部类才可以引用

作者: 黑马王建伟    时间: 2012-8-22 15:15
一:

  1. public class Outer {
  2.         private String info="Hello World";
  3.         public class Inner{
  4.                 public void print(){
  5.                         System.out.println("可直接访问外部类的变量:"+info);
  6.                 }
  7.         }
  8.         public static void main(String[] args) {
  9.                 Outer o=new Outer();//实例化外部类
  10.                 Outer.Inner in=o.new Inner();//实例化内部类
  11.                 in.print();//打印结果:可直接访问外部类的变量:Hello World
  12.         }
  13. }
复制代码
二:

  1. public class Hello {
  2.         private String info="Hello World";
  3.         public void print(final int a){
  4.                 class Inner{
  5.                         public void test(){
  6.                                 System.out.println("访问外部类中的参数不用final修饰:"+info);
  7.                                 System.out.println("访问外部类中方法中的内部类,要访问方法中的参数,一定要加final:"+a);
  8.                         }
  9.                 };
  10.                 new Inner().test();//在方法中实例化内部类,用调用内部类中的test()方法;
  11.         }
  12.         public static void main(String[] args) {
  13.                 Hello h=new Hello();
  14.                 h.print(33);
  15.                 //运行结果:
  16. //                访问外部类中的参数不用final修饰:Hello World
  17. //                访问外部类中方法中的内部类,要访问方法中的参数,一定要加final:33
  18.         }
  19. }
复制代码
相信楼主看了会明白些--------------------------------------
作者: 刘芮铭    时间: 2012-8-22 15:16
局部内部类(包括匿名局部内部类和普通内部类)中使用局部变量,那么这个局部变量必须使用final修饰。这里说的是局部内部类,不是普通静态内部类和非静态内部类,因为他们不能访问方法体内的局部变量。
java要求所有被局部内部类访问的局部变量都是用final修饰是因为:对于普通局部变量他的作用域就是该方法内,当方法结束该局部变量就随之消失;但局部内部类可能产生隐式的“闭包”,闭包将使得局部变量脱离他所在的方法继续存在

作者: 邓超军    时间: 2012-8-22 15:33
我觉得应该从变量的生命周期来理解。
局部变量的生命周期和所在函数的生命周期相同;而内部类的对象生命周期和外部类对象的生命周期相同,要比局部变量的生命周期长;局部变量被final修饰后的生命周期和外部类生命周期相同。
所以,我觉得这是一个规则:一个方法(或类)只能访问生命周期大于等于其生命周期的变量,而不能访问小于其生命周期的变量。
作者: 朱烈葵    时间: 2012-8-22 15:35
黑马王建伟 发表于 2012-8-22 15:15
一:二:相信楼主看了会明白些--------------------------------------

我明白啊,可是这到底是为什么呢,为什么被final修饰才有用
作者: 朱烈葵    时间: 2012-8-22 15:38
刘芮铭 发表于 2012-8-22 15:16
局部内部类(包括匿名局部内部类和普通内部类)中使用局部变量,那么这个局部变量必须使用final修饰。这里 ...

好,要的就是这个答案,很给力啊
作者: 朱烈葵    时间: 2012-8-22 15:40
李知伦 发表于 2012-8-22 15:12
在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可 ...

谢谢帮忙,问题已经解决了
作者: 朱烈葵    时间: 2012-8-22 15:42
邓超军 发表于 2012-8-22 15:33
我觉得应该从变量的生命周期来理解。
局部变量的生命周期和所在函数的生命周期相同;而内部类的对象生命周 ...

嗯 嗯的 是的 是的

作者: 朱烈葵    时间: 2012-8-22 15:44
问题已解决,谢谢各位了!
作者: 刘芮铭    时间: 2012-8-22 15:45
朱烈葵 发表于 2012-8-22 15:38
好,要的就是这个答案,很给力啊

那就将标题写上“已解决”吧   不客气
作者: 郑文    时间: 2012-8-24 20:01
我不学JAVA 我学.net的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2