//代码示例
import java.util.*;
import static net.mindview.util.Print.*;
class Value{
int i;
public Value(int i){this.i=i};
}
public class FinalData{
private static Random rand=new Random(47);
private String id;
public FinalData(String id){this.id=id;}
private final int valueOne=9;//私有final成员
private static final int VALUE_TWO=99;//静态私有final成员
public static final int VALUE_THREE=39;
private final int i4=rand.nextInt(20);
static final int INT_5=rand.nextInt(20);
private Value v1=new Value(11);
private final Value v2=new Value(22);
private static final Value VAL_3=new Value(33);
private final int[] a={1,2,3,4,5,6};
public String toString(){
return id+": "+"i4= "+i4+", INT_5= "+INT_5;
}
public static void main(String args[])
{
FinalData fd1=new FinalData("fd1");
//error: fd1.valueOne++;
fd1.v2.i++; //注意:成员v2是final修饰;但是v2表示的是引用而非对象本身
fd1.v1=new Value(9);
for(int i=0;i<fd1.a.length;i++)
{
fd1.a[i]++;
//error:fd1.v2=new Value(0);
//error:fd1.VAL_3=new Value(1);
//error:fd1.a=new int[3];
}
print(fd1);
print("Creating new FinalData");
FinalData fd2=new FinalData("fd2");
print(fd1);
print(fd2);
}
};
//输出结果
fd1: i4= 15, INT_5= 18
Creating new FinalData
fd1: i4= 15, INT_5= 18
fd2: i4= 13, INT_5= 18
首先看输出结果:fd1与fd2对比,i4结果发生了变化,INT_5没有变,i4的修饰符是private 和 final ;INT_5的修饰符是static 和final;由于i4仅仅只是私有的final成员,所以不同对象的引用所具有的i4的值当然可以不同,但是相同对象的i4的值不可以发生变化;而INT_5因为是static的成员,并且也有final关键字修饰,所以INT_5是该类共有的成员,而且不可以发生改变;
再来看几条error;第一条error是对fd1.valueOne自加发生的错误;
private final int valueOne=9;这条语句表示valueOne成员是一个私有的final成员并且初始化为9;所以任何对其进行改变的语句都是错误的;
v2是Value对象的引用,同时也有final修饰,当出现final修饰对象的引用时,表示对象本身可变,但是该引用只能指向该对象(即引用不可变);
VAL_3是private和static和final修饰的成员,也是一个对象的引用,所以无法将它改变指向其他对象;
关于数组,数组也是对象的引用,所以无法改变指向的对象;
总结:
final关键字修饰基本数据类型,对象的引用,成员方法,数组,类;
1:修饰基本数据类型是,表示该变量不可变;
2:修饰对象引用时,表示该对象的引用不可变,只能指向该对象,对象本身可以改变;
3:修饰成员方法时,表示该方法不可变且继承时不会被覆盖;
4:数组和对象引用类似,可以看作引用的集合;
5:修饰类,表示该类不想改变也不可以被继承;