标题: 程序里的i为什么要设成final类 [打印本页] 作者: 何艳梅 时间: 2014-8-7 23:18 标题: 程序里的i为什么要设成final类 public class Interf {
static void function() {
int i =0;
class A {
void fun() {
i ++;
}
}
现在我们来看,如果我要实现一个在一个方法中匿名调用ABSClass的例子: public static void test(final String s){ //或final String s = "axman"; ABSClass c = new ABSClass(){ public void m(){ int x = s.hashCode();
System.out.println(x);
} }; //其它代码. }
从代码上看,在一个方法内部定义的内部类的方法访问外部方法内局部变量或方法参数,是非常自然的事,但内部类编译的时候如何获取这个变量,因为内部类除了它的生命周期是在方法内部,其它的方面它就是一个普通类。那么它外面的那个局部变量或方法参数怎么被内部类访问?编译器在实现时实际上是这样的:
public static void test(final String s){ //或final String s = "axman";
class OuterClass$1 extends ABSClass{
private final String s; public OuterClass$1(String s){ this.s = s; } public void m(){ int x = s.hashCode();
System.out.println(x);
} };
ABSClass c = new OuterClass$1(s); //其它代码. }
即外部类的变量被作为构造方法的参数传给了内部类的私有成员. 假如没有final,那么: public static void test(String s){ //或String s = "axman"; ABSClass c = new ABSClass(){ public void m(){ s = "other"; } }; System.out.println(s); } 就会编译成: public static void test(String s){ //或String s = "axman";
class OuterClass$1 extends ABSClass{
private String s; public OuterClass$1(String s){ this.s = s; } public void m(){ s = "other";
} }; ABSClass c = new OuterClass$1 (s);
}
内部类的s重新指向"other"并不影响test的参数或外部定义的那个s.同理如果外部的s重新赋值内部类的s也不会跟着改变。 而你看到的 public static void test(String s){ //或String s = "axman"; ABSClass c = new ABSClass(){ public void m(){ s = "other"; } }; System.out.println(s); }