Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
来源:互联网 发布:自动排班软件那个好 编辑:程序博客网 时间:2024/05/18 00:00
Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
我们来看看Java对内部类的实现。
使用内部类经常是用在Listener这样的。而Listener中的监听函数被调用时,大部分情况,new内部类所在的函数早就执行完了,此时外部类局部变量(保存在栈中)早就因为函数的退出而失效了。
而加上final后,编译器是这样处理内部类的。如果这个外部局部变量是常量,则在内部类代码中直接用这个常量。如果是类的实例,则编译器将产生一个内部类的构造参数,将这个final变量传到内部类里,这样即使外部局部变量无效了,还可以使用。
例如:
01
import
java.util.*;
02
03
public
class
Test{
04
public
void
run() {
05
final
List a=
new
ArrayList();
06
class
B{
07
public
int
c;
08
public
void
run(){
09
List b;
10
b=a;
11
System.out.println(b);
12
}
13
};
14
15
B b=
new
B();
16
17
b.c=
0
;
18
}
19
}
使用javap -private Test$1B(这个就是内部类)将看到
Compiled from "Test.java"
class Test$1B extends java.lang.Object{
public int c;
private final java.util.List val$a;
private final Test this$0;
Test$1B(Test,java.util.List);
public void run();
}
而下面是使用常量的例子:
01
public
class
Test{
02
public
void
run() {
03
final
int
a=
100
;
04
class
B{
05
public
int
c;
06
public
void
run(){
07
int
b;
08
b=a;
09
System.out.println(b);
10
}
11
};
12
13
B b=
new
B();
14
15
b.c=
0
;
16
}
17
}
javap -private -c Test$1B:
Compiled from "Test.java"
class Test$1B extends java.lang.Object{
public int c;
private final Test this$0;
Test$1B(Test);
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: putfield #2; //Field this$0:LTest;
9: return
public void run();
Code:
0: bipush 100
2: istore_1
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: iload_1
7: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
10: return
}
另外引用别人的一段话:
内部类并不是直接调用方法传进来的参数,而是内部类将传进来的参数通过自己的构造器备份到了自己的内部,自己内部的方法调用的实际是自己的属性而不是外部类方法的参数。
这样理解就很容易得出为什么要用final了,因为两者从外表看起来是同一个东西,实际上却不是这样,如果内部类改掉了这些参数的值也不可能影响到原参数,然而这样却失去了参数的一致性,因为从编程人员的角度来看他们是同一个东西。
如果我们不强制使用final的话,那么编程人员在程序设计的时候在内部类中改掉参数的值,但是外部调用的时候又发现值其实没有被改掉,这就让人非常的难以理解和接受,为了避免这种尴尬的问题存在,所以编译器设计人员把内部类能够使用的参数设定为必须是final来规避这种莫名其妙错误的存在。
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- [Java] 匿名内部类访问外部类的局部变量为什么一定得是final类型
- 内部类引用外部类局部变量,外部类局部变量必须是final
- 内部类引用外部类局部变量
- Java内部类引用外部类中的局部变量为何必须是final问题解析
- Java内部类引用外部类中的局部变量为何必须是final问题解析
- Java内部类引用外部类中的局部变量为何必须是final问题解析
- Java内部类引用外部类中的局部变量为何必须是final?
- java中内部类访问局部变量为什么要定义局部变量为final
- 局部内部类+外部类访问final变量+final 回顾
- 局部内部类引用外部类中的局部变量必须是final属性的!
- 局部内部类引用外部类中的局部变量必须是final属性的!
- 局部内部类引用外部类中的局部变量必须是final属性的!
- 局部内部类引用外部类中的局部变量必须是final属性的!
- 前言——一步步学习jQuery EasyUI
- C03-Java同步实践加强班第4周上机任务
- 灵活定点格式
- 英语练习My HomeTown
- 解析char *p与char p[] 区别
- Java中为什么内部类对外部类局部变量有引用时,外部类局部变量一定要有final?
- Linux和Windows平台memcached server的安装
- ExtJs xtype 一览表
- [转]error - Operation is not valid due to the current state of the object.
- 【索引】AOAPC I: Beginning Algorithm Contests (Rujia Liu)
- DrawPrimitive()
- centos定制
- Forms表单验证 使用经验及验证流程分析
- redmine安装过程