内部类访问的局部变量必须加final

(1)内部类是外部类的一个成员,就像外部类的成员方法一样,所以内部类有权限访问外部类的所有成员,包括private的。

(2)内部类不能访问外部类方法中的局部变量,除非变量是final的(一般发生在方法中定义的内部类)。这是因为局部变量的生命周期原因。

class Outer{

private int a;

public class Inner{

private int a;

public void method(int a){

a++;    //局部变量

this.a++;    //Inner类变量

Outer.this.a++;    //Outer类变量

}

}

}


一般做法是在Outer中写一个返回Inner类对象的方法

public Inner getInner(){

return new Inner();

}    在其他类中使用内部类:

Outer outer = new Outer();

Outer.Inner inner = outer.new Inner(); 或者 Outer.Inner inner = outer.getInner();

static内部类的使用:  Outer.Inner inner = new Outer.Inner();

(1).所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,却必须要加上一个final。

(2).原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命期。局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命期,与其它类一样,当创建一个局部内部类对象后,只有当没有其它人再引用它时,它才能死亡。所以完全可能一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。

(3).局部内部类的对象访问同一个方法中的局部变量,那么这就要求只要局部内部类对象还活着,那么栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?)。这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。

(4).解决方法:局部内部类的对象可以访问同一个方法中被定义为final的局部变量。定义为final后,编译程序的实现方法:将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。(这一点我有些怀疑)

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

final 补充说明:

1.在java中声明类、属性、方法时,可使用关键字final来修饰

2.final标记的类不能被继承。

3.final标记的方法不能被子类重写

4.final标记的变量(成员变量或局部变量)即成为常量,只能赋值一次。

5.final标记的变量必须在声明的同时或在构造方法中显示赋值,然后才能使用。

final int x = 5;

class Test{

final int x ;

Test(){

x=3;

}  }

时间: 2024-12-14 06:43:37

内部类访问的局部变量必须加final的相关文章

JDK7中匿名内部类中使用局部变量要加final,JDK8中不需要,但jdk会默认加上final

今天看书的时候看到了局部内部类,书上说局部内部类可以访问局部变量,但是必须是final的.因为局部变量在方法调用之后就消失了,使用final声明的话该局部变量会存入堆中,和内部类有一样的声明周期.但是我写了一个局部内部类,竟然可以访问非final的局部变量,请问这是什么回事呢.ps:我的jdk是8 难道和这个有关系? public class jubuneibulei { public void p(int a, int b){ class te{ void print(){ System.ou

JAVA中内部类(匿名内部类)访问的局部变量为什么要用final修饰?

本文主要记录:在JAVA中,(局部)内部类访问某个局部变量,为什么这个局部变量一定需要用final 关键字修饰? 首先,什么是局部变量?这里的局部是:在方法里面定义的变量. 因此,内部类能够访问某局部变量,说明这个内部类不是在类中定义的内部类,而是在方法中定义的内部类,称之为:局部内部类. 局部变量的作用域:局部变量是在某个方法中定义,当该方法执行完成后,局部变量也就消失了.[局部变量分配在JVM的虚拟机栈中,这部分内存空间随着程序的执行自动回收],也即:局部变量的作用域是在 “方法的范围内”.

final运用于内部类访问局部变量

public void mRun( final String name){ new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name); } }.run(); } 当内部类访问局

为什么java内部类访问局部变量必须声明为final?

https://blog.csdn.net/z55887/article/details/49229491 先抛出让我疑惑了很久的一个问题 编程时,在线程中使用局部变量时候经常编译器会提示:局部变量必须声明为final package test; public class ThreadTest { public void function(String a) { new Thread(){ @Override public void run() { System.out.println(a);

内部类访问局部变量的时候,为什么变量必须加上final修饰

这里的局部变量就是在类方法中的变量,能访问方法中变量的类当然也是局部内部类了.我们都知道,局部变量在所处的函数执行完之后就释放了,但是内部类对象如果还有引用指向的话它是还存在的.例如下面的代码: class Outer{ public static void main(String[] args){ Outer out = new Outer(); Object obj = out.method(); } Object method(){ int locvar = 1; class Inner{

匿名内部类为什么访问外部类局部变量必须是final的?

1.内部类里面使用外部类的局部变量时,其实就是内部类的对象在使用它,内部类对象生命周期中都可能调用它,而内部类试图访问外部方法中的局部变量时,外部方法的局部变量很可能已经不存在了,那么就得延续其生命,拷贝到内部类中,而拷贝会带来不一致性,从而需要使用final声明保证一致性.说白了,内部类会自动拷贝外部变量的引用,为了避免:1. 外部方法修改引用,而导致内部类得到的引用值不一致 2.内部类修改引用,而导致外部方法的参数值在修改前和修改后不一致.于是就用 final 来让该引用不可改变. 2.内部

内部类访问外部类的变量必须是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

Android(java)学习笔记150:为什么局部内部类只能访问外部类中的 final型的常量

为什么匿名内部类参数必须为final类型: 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的,是很自然的. 2) 为什么JAVA中要加上一条限制:只能访问final型的局部变量? JAVA语言的编译程序的设计者当然全实现:局部内部类能访问方法中的所有的局部变量(因为:从理论上这是很自然的要求),但是:编译技术是无法实现的或代价极高. 至于为什么只能是fi

局部内部类访问局部变量的问题

局部内部类访问局部变量的注意事项: 局部变量必须用final修饰! 为什么?   因为局部变量是随着方法的调用而调用,随着调用完毕而消失 但是我们调用内部类时创建的对象依旧在堆内存中,并没有被回收,如果访问的局部变量不是用final修饰的,就是当方法调用完毕后,依旧存在于堆内存中的对象找不到局部变量的问题 而此时被final修饰的变量可以看成是一个常量,存在于常量池中,不会被立刻回收. 原文地址:https://www.cnblogs.com/afei1013/p/12349608.html