final关键字:保证被修饰的非抽象类、非抽象类成员方法和变量是最终态的
(网上收集)
但有种情况final不能保证被修饰的变量不会被改变:
class Final
{
public static void main(String[] args)
{
Color.color[3] = "white";
for (String color : Color.color)
System.out.print(color+" ");
}
}
class Color
{
public static final String[] color = { "red", "blue", "yellow", "black" };
}
//result:red blue yellow white
这个时候观察结果,发现“black”还是变成了white
原因是final只是让color这个引用不能被重新绑定(赋值),但是color这个引用的内部数据是可以更改的.
在wiki上有这样一张图:
final关键字的灵活性:
final是在被赋值一次后就不能再赋值了,但也只能在construct method和static块还有被定义时赋值:
class FinalTest {
private final int num1 = 1;
private final int num2;
private final int num3;
static {
this.num2 = 1;
}
public FinalTest(int num) {
num3 = num;
}
}
这一定程度上使final关键字有了一定的灵活性
其实以上所有的描述 都可以化为下面一段代码:
public class Bat{
final PI=3.14; //在定义时便给址值
final int i; //因为要在构造方法中进行初始化,所以此处便不可再给值
final List list; //此变量也与上面的一样
Bat(){
i=100;
list=new LinkedList();
}
Bat(int ii,List l){
i=ii; //可以在构造方法/static块中给final修饰的变量赋值,让final更加灵活
list=l;
}
public static void main(String[] args){
Bat b=new Bat();
b.list.add(new Bat()); //可以修改final修饰的引用对象的内部数据
//b.i=25;
//b.list=new ArrayList(); //报错,被final修饰的引用不能被再次绑定
System.out.println("I="+b.i+" List Type:"+b.list.getClass());
b=new Bat(23,new ArrayList());
b.list.add(new Bat());
System.out.println("I="+b.i+" List Type:"+b.list.getClass());
}
}