//代码示例

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:修饰类,表示该类不想改变也不可以被继承;