`
zhchx0827
  • 浏览: 191547 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

方法中的内部类不能访问该方法的局部变量

 
阅读更多

 

原文链接:http://blog.csdn.net/shouwangsiwang/article/details/8165219

 

1)所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,是天经地义的。那么为什么要加上一个final呢? 
2)原因是:编译程序实现上的困难,难在何处:内部类对象的生命周期会超过局部变量的生命期。为什么?表现在:局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建(诞生),当方法调用结束时(执行完毕),退栈,这些局部变量全部死亡。而:内部类对象生命期,与其它类一样,当创建一个该局部类对象后,只有没有其它人再引用它时,它才能死亡。完全可能:一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。 
3)退一万步:局部类的对象生命期会超过局部变量又怎样?问题的真正核心是:如果:局部内部类的对象访问同一个方法中的局部变量,是天经地义的,那么:只要局部内部类对象还活着,则:栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?),这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。而:正是这一点是不可能做到的 
4)但是从理论上:局部内部类的对象访问同一个方法中的局部变量,是天经地义的。所以:经过努力,达到一个折中结果:即:局部内部类的对象可以访问同一个方法中的局部变量,只要这个变量被定义为final.那么:为什么定义为final变可以呢?定义为final后,编译程序就好实现了:具体实现方法是:将所有的局部内部类对象要访问的final型局部变量,变成该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。

归纳上述回答的真正核心是:局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。因此,正是在这个意义上,final型局部变量的生命期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量(含final)全死亡了。但:局部内部类对象中有final型局部变量的拷贝。

其他:

不管对象是不是final,他的生命周期都是 new开始,垃圾回收结束。 
不管变量是不是final,他的生命周期都在于{}中。 

类对象(class对象)与其它对象不同,类对象的生命周期 开始于类被加到内存中那一刻,结束于垃圾回收。 
类变量(static)与类对象的生命周期相同。

 

  1. public class LocalInnerClassTest{  
  2.       public static void main(String[] args){  
  3.          Outer obj=new Outer();          //生成一个外部类对象  
  4.          SuperInner si=obj.outer();        //调用外部类中的outer()方法,返回一个SuperInner类型对象赋值给si  
  5.         si.m1();             //调用被覆盖的方法m1(),输出:Inner's m1() 20  
  6.      }  
  7. }  
  8.   
  9. /** 
  10. *定义一个接口SuperInner,内部定义一个抽象方法m1(),无返回类型 
  11. */  
  12. interface SuperInner{  
  13.      public void m1();  
  14. }  
  15.   
  16. /** 
  17. *定义一个类Outer,内部只定义一个方法outer(),返回类型为SuperInner 
  18. */  
  19. class Outer{  
  20.      public SuperInner outer(){  
  21.         int a=10;                   //方法中定义一个局部变量a,并赋值为10  
  22.         final int b=20;          //再定义一个final局部变量b,初始化为20  
  23.   
  24.         class Inner implements SuperInner{              //在outer()方法中定义一个局部内部类Inner,实现接口SuperInner  
  25.            public void m1(){    //类中只有一个覆盖接口SuperInner的方法m1()  
  26.               System.out.println("Inner's m1()"+a);    //编译报错  
  27.               System.out.println("Inner's m1() "+b);    //编译通过,输出:Inner's m1() 20  
  28.            }  
  29.         }  
  30.         return new Inner();  
  31.      }  

分享到:
评论

相关推荐

    Java中局部内部类可以访问它所在方法中定义的final修饰的局部变量的合理解释.doc

    Java中局部内部类可以访问它所在方法中定义的final修饰的局部变量的合理解释.doc

    Java实例变量、类变量、局部变量

    类变量是类中的静态变量,是用static修饰的变量;实例变量就是类中的成员变量,没有用static修饰的。 类变量是所有对象公用的,实例变量是对象私有的;当一个对象将类变量进行修改...局部变量,即定义在方法内部的变量。

    局部内部类访问外边的局部变量---马克-to-win java视频

    局部内部类访问外边的局部变量 马克-to-win java视频的介绍

    Python语言基础:局部变量和全局变量.pptx

    局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。 对于全局变量和局部变量,即使变量名相同,但是因为定义在不同的作用...

    函数的全局和局部作用域和变量-作用域.html

    函数的变量和作用域 /全局变量和全局作用域指的是变量或者函数的位置 // 全局变量: 在script之间或者一个独立的js文件中,在全局作用域中定义的变量 全局变量。...局部变量只有在定义该变量的函数中可以访问

    【05-面向对象(下)】

    名字的局部变量,就使用该变量,如果不存在,则到该方法所在的内部类中查找是否存在该名字的属性,如果存在 则使用该属性。 •总之,第一步先找局部变量,第二步,内部类的属性,第三步。外部类的属性。 ...

    深入理解Java?内部类

    什么是内部类?  内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附...  (3)、内部类声明成静态的,不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。

    PHP函数 -变量的作用域.ppt

    一、局部变量 局部变量是在函数内部定义的变量,其作用域仅限于函数内部,离开该函数后再使用此变量是非法的。另外,函数定义中的普通形参由于只能在本函数内部使用,因此也是局部变量。 二、全局变量 全局变量是指...

    测量程序编制 - python A2面向对象-类实例变量与局部变量.pptx

    面向对象——类实例变量与局部变量;实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。另外,实例变量只能通过对象名访问,无法通过类名访问。;上面程序中,...

    Python变量在函数中的作用域.md

    Python中局部变量的声明和作用范围; 嵌套函数中的局部变量的作用范围; 如何在函数内部访问外层函数的变量。 能学到什么 通过阅读本文,您将学会以下内容: 在编写Python函数时如何正确声明和使用局部变量; 嵌套...

    PHP变量作用域(全局变量&局部变量)&global&static关键字用法实例分析

    本文实例讲述了PHP变量作用域(全局变量&局部变量)&global&static关键字用法...除了函数外,全局变量可以被脚本中的任何部分访问,要在一个函数中访问一个全局变量,需要使用 global 关键字。然而,在 PHP 函数内部声

    java日常词汇学习

     Access modifier 访问控制修饰符:访问控制修饰符用来修饰Java中类、以及类的方法和变量的访问控制属性。  Anonymous class 匿名类:当你需要创建和使用一个类,而又不需要给出它的名字或者再次使用的使用,就...

    Student.java

    1:局部内部类还可以访问成员变量 2:静态内部类可以访问外部类的所有成员和方法 3:成员内部类可以访问外部类的所有属性和方法 OutputStream抽象类中的方法 abstract void write(int n) 写出一个字节的数据 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    4.5 语句中不能不说的事 84 4.5.1 小心复杂语句中创建的变量 85 4.5.2 别让循环次数给弄懵了 86 4.5.3 循环的嵌套 87 4.6 continue关键字与break关键字 88 4.6.1 continue关键字 88 4.6.2 break关键字 89 4.7...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    4.5 语句中不能不说的事 84 4.5.1 小心复杂语句中创建的变量 85 4.5.2 别让循环次数给弄懵了 86 4.5.3 循环的嵌套 87 4.6 continue关键字与break关键字 88 4.6.1 continue关键字 88 4.6.2 break关键字 89 4.7...

    Java学习笔记(必看经典)

    局部变量不允许范围内定义两个同名变量。实例变量的作用域在本类中完全有效,当被其他的类调用的时候也可能有效。 实例变量和局部变量允许命名冲突。 书写方法的格式: 修饰符 返回值 方法名 调用过程中 方法体 ...

    day022-jdk8新特性和lambda表达式 代码和笔记.rar

    1. lambda: 1. 概念:就是对函数式接口匿名内部类的简写 2.... 3.... 函数式接口 变量名 = (参数1,参数2...) -> { ... 若是局部变量没有加final关键字,系统会自动添加,此后在修改该局部变量,会报错;

    Java学习笔记-超强笔记

    实例变量的作用域至少在本类内部,受访问控制符的限制。 在重合作用域,实例变量和局部变量允许有命名冲突,“局部优先”。 定义方法: 格式: [ 修饰符 ] 返回类型 方法名( 参数列表 ) [ throws ...

    Python语言基础:作用域.pptx

    Python的作用域一共有4种,分别是:L(Local):最内层,包含局部变量,比如一个函数/方法内部。E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又...

    测量程序编制 - python 91函数-作用域(局部变量).pptx

    局部变量(Local Variable):在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了。 当函数被执行时,Python 会为其分配一块临时的存储空间,所有在函数内部定义的变???,都会存储在这块空间...

Global site tag (gtag.js) - Google Analytics