Java内部类引用外部类中的局部变量为何必须是final问题解析

今天编写一个多线程程序,发现在方法内定义内部类时,如果内部类调用了方法中的变量,那么该变量必须申明为final类型,百思不得其解,后来想到应该 是生命周期的原因,因为方法内定义的变量是局部变量,离开该方法,变量就失去了作用,也就会自动被消除,而内部类却不会离开它所在方法就失去作用,它有更 广的生命周期,下面通过一个实例加以说明:

如例中所示,在外部类Outer中声明了一个内部类TimerPrint,这个类中的方法引用了方法start中的一个局部变量testTxt

逻辑上:因为该内部类出现在一个方法的内部,但实际编译时,内部类编译为Outer$1TimerPrint.class,这说明,外部类的这个方法和内
部类是处于同一级别的。换句话说是非final变量和内部类的生命周期不一样!start被调用后,非final变量也会随之消失,就会出现内部类引用非
法!

实际做法:Java编译器的行为是这样的(前提条件是该变量在内部类中被引用):

若定义为final,则java编译器则会在内部类TimerPrint内生成一个外部变量的拷贝,而且可以既可以保证内部类可以引用外部属性,又能保证值的唯一性。

若不定义为final,则无法通过编译!(jdk1.6测试过)。因为编译器不会给非final变量进行拷贝,那么内部类引用的变量就是非法的!

下面看经过编译以后的字节码:

外部类编译后的字节码:

内部类编译后的字节码:

如果外部类中的变量d没有被内部类引用,则final为可选的,而且java编译器将不做特殊处理!!

加一个参数d 并且把它定义为非final类型,编译以后文件如下:

编译后的外部类class:

编译后的内部类class: 

由上可以看出,在方法内部定义内部类时,内部类如果调用了方法内的变量,则该变量必须被final修饰,否则就会因为在调用内部类时因为找不到所用的变量而报错!

文章引自---blog.csdn.net/zzp_403184692/article/details/8014235

时间: 2024-08-09 22:00:08

Java内部类引用外部类中的局部变量为何必须是final问题解析的相关文章

Java内部类持有外部类的引用详细分析与解决方案

在Java中内部类的定义与使用一般为成员内部类与匿名内部类,他们的对象都会隐式持有外部类对象的引用,影响外部类对象的回收. GC只会回收没有被引用或者根集不可到达的对象(取决于GC算法),内部类在生命周期内始终持有外部类的对象的引用,造成外部类的对象始终不满足GC的回收条件,反映在内存上就是内存泄露.(如,Android中Activity的内存泄露) 解决方案为 1.将内部类定义为static 2.用static的变量引用匿名内部类的实例 测试代码 class Outer { class Inn

java 内部类与外部类的区别

最近在看Java相关知识的时候发现Java中同时存在内部类以及非公有类概念,而且这两个类都可以不需要单独的文件编写,可以与其他类共用一个文件.现根据个人总结将两者的异同点总结如下,如有什么不当地方,欢迎大家指正. 1.非公有类和内部类对应的文件名与这两种类的类名无关: 2.一个源文件中可以包含多个非公有类或者内部类: 3.非公有类不能使用public关键字(一般前面不加关键字),内部类可以使用public.private.protected关键字: 4.非公有类中可以添加0到多个内部类: 5.非

Java内部类与外部类的那些事

昨天去笔试的时候遇到了Java的内部类的创建方式与访问权限的问题,我不懂,没写,故今天起来特意去试验一下,就有了这篇总结性的文章. Java中的内部类又分为非静态内部类(匿名内部类也是非静态的内部类)和静态内部类,两者与外部类的关系是不一样的,创建的方式也不一样. 1 非静态内部类 Java的非静态内部类在构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,因此,内部类会隐式地持有其外部类的引用.也就是非静态内部类在构造的时候需要有一个外部类的实例传递进来进行构造,不能像普通的Jav

java内部类和外部类

1.使用static可以声明一个内部类, 可以直接在外部调用 class Outer{ // 定义外部类 private static String info = "hello world" ; // 定义外部类的私有属性 static class Inner{ // 使用static定义内部类为外部类 public void print(){ // 定义内部类的方法 System.out.println(info) ; // 直接访问外部类的私有属性 } }; public void

python中的嵌套类(内部类调用外部类中的方法函数)

在为书中版本是3.X的,但2.X不太支持直接调用. 所以,在PYTHON2.X中,要在内部类中调用外部类的方法,就必须得实例化外部类,然后,传入实例进行调用. 花了我两个小时啊,资料没找到,自己一个一个想法调试,真的失败了三四十次,PRINT了N多~~~:) class DiagramFactory: @classmethod def make_diagram(Class, width, height): return Class.Diagram(width, height) @classmet

java:内部类与外部类的区别和联系

注意事项一:在内部类中可以随意使用外部类的成员方法以及成员变量. 众所周知,在定义成员方法或者成员变量的时候,可以给其加上一些权限的修饰词,以防止其他类的访问.如在成员变量或者成员方法前面,加上Private 关键字,则其他类就无法调用这个类中的成员方法或则和成员变量.但是,如果这个类有成员内部类,则不受这方面的限制.也就是说,在成员内部类中可以随意引 用外部类的成员方法以及成员变量,即使这些类成员方法或者成员变量被修饰了private.如在成员外部类中定义了一个i变量,并且利用private关

内部类和外部类的实例变量可以共存

成员内部类:作为外部类的一个成员存在,与外部类的属性.方法并列. 内部类和外部类的实例变量可以共存. 在内部类中访问实例变量:this.属性 在内部类访问外部类的实例变量:外部类名.this.属性. 成员内部类的优点: ⑴内部类作为外部类的成员,可以访问外部类的私有成员或属性.(即使将外部类声明为PRIVATE,但是对于处于其内部的内部类还是可见的.) ⑵用内部类定义在外部类中不可访问的属性.这样就在外部类中实现了比外部类的private还要小的访问权限. 注意:内部类是一个编译时的概念,一旦编

内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例

内部类访问外部类的变量必须是final吗? 如下:class A{int i = 3;public void shout(){ class B{public void shout1(){System.out.println(i);} }B b=new B();b.shout1();} public static void main(String [] args){A a=new A();a.shout();} }可正常输出3,证明可以访问类的变量i,但改为下面的方式:class A{public

java 第44节 引用外部类的对象

2016-06-30 package com.java1995; /** * 1.引用外部类的对象 * Inner: this.count * Outer:Outer.this.count * @author Administrator * */ //外部类 public class Outer { private int count =1 ; //内部类 class Inner{ private int count = 2; //内部类的方法 public void print(int cou