那我们到底为什么要对参数加上final?其实对方法参数加final和方法内变量加上final的作用是相同的,即为了将它们
传给内部类时保证调用的一致性:
abstract class ABSClass{
public abstract void m();
}
现在我们来看,如果我要实现一个在一个方法中匿名调用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";
ABSClass c = new ABSClass(s){
private final String s;
public ABSClass(String s){
this.s = s;
}
public void m(){
int x = s.hashCode();
System.out.println(x);
}
};
//其它代码.
}
即外部类的变量被作为构造方法的参数传给了内部类的私有成员.
假如没有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";
ABSClass c = new ABSClass(s){
private final String s;
public ABSClass(String s){
this.s = s;
}
public void m(){
s = "other";
}
};
System.out.println(s);
}
内部类的s重新指向"other"并不影响test的参数或外部定义的那个s.而你看到的
public static void test(String s){
//或String s = "axman";
ABSClass c = new ABSClass(){
public void m(){
s = "other";
}
};
System.out.println(s);
}
同理如果外部的s重新赋值内部类的s也不会跟着改变。
在语法上是一个s,在内部类中被改变了,但结果打印的出来的你认为是同一的s却还是原来的"axman",
你能接收这样的结果吗?
所以final从语法上约束了两个不同变量的一致性.
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/neusoftware_20063500/archive/2009/02/18/3907755.aspx
本文探讨了在Java中为何需要对内部类方法参数使用final修饰符,通过实例解释了final如何确保内外部变量一致性,避免因变量指向变化导致的意外行为。

被折叠的 条评论
为什么被折叠?



