final 恒定数据
final关键字包括数据、方法、类。
final一般来说两种情况:
1.恒定不变的编译时常量。
2.数据初始化时即确定的常量值不可改变。
按照数据类型又分基本数据类型如:int、char、float等和引用类型如:String。
基本类型较为简单,如果我们在声明时就给定初值,就不可在改变。可以在变量声明时不初始化即空白final声明为final不给定初值,但是在使用前必须初始化。
引用类型一旦声明了final后,引用不可改变,但是引用类型存储的是地址,故引用不可变,引用内容可变,即不可以改变引用所指向的对象,但可以改变对象自身。
以一段代码为例,
import java.util.*;
public class FinalData{
/*引用了util包中的random类,此new random对象是创建了一个随机数种子
即同一随机种子创建出来的随机序列是固定的*/
private static Random rand = new Random(99);
private String id;
private final int c ;
private int d;
//带参构造器改变成员变量从而改变了对象
public FinalData(String id){
this.id = id;
c = 6;//在构造器中也可以初始化
}
private final int valueone = 1;
private static final int VALUE_TWO = 2;
public static final int VALUE_THREE = 3;
//指定了两个随机整型,运行时确定的常量
private final int int4 = rand.nextInt(20);
static final int INT_5 = rand.nextInt(20);
//Value引用类型,用于改变final对象
private final Value value1 = new Value(11);
private final Value Value_2 = new Value(22);
private static final Value VALUE_3 = new Value(33);
//引用类型的数组,可改变数组值不能重新初始化数组
private final int [] a = {1,2,3,4,5,6};
public String toString(){
return id + ":" + " int4 " + int4 + ", INT_5 " + INT_5 ;
}
public static void main(String args[]){
final int b ;
b=5;
FinalData fd1 = new FinalData("fd1");
fd1.c = 6;//为已初始化的值赋值报错
fd1.valueone++;//cannot assign a value to final variable valueone
fd1.Value_2.i++;
fd1.value1 = new Value(9);//不能改变final变量
fd1.a = new int[5];//不能改变数组变量
for(int i=0;i<fd1.a.length;i++){
fd1.a[i]++;//改变引用类型数组值
}
FinalData fd2 = new FinalData("fd2");
System.out.print(fd1);
System.out.println(fd2);
System.out.println(b+fd1.c);
}
}
class Value{
int i;
public Value(int i){ this.i = i; }
}
/*********************************************************/
运行结果
fd1: int4 18, INT_5 7fd2: int4 9, INT_5 7
11
可以看到的是int4 和 INT_5的区别就是静态和非静态的区别,静态变量在类初始化装载时就确定了,而非静态变量在对象初始化时才确定,即非静态变量随着创建对象不同而改变值。Value类型的对象通过i变量发生改变。
空白final的用处
final变量不在定义时初始化,有极大的灵活性。一个类中的final变量可以根据对象的不同,有不同的值。
public class BlankFinal{
private final int i;
private final Help h1;
public BlankFinal(){
i = 1;
h1 = new Help(1);
}
public BlankFinal(int ii){
i = ii;
h1 = new Help(ii);
}
public static void main(){
new BlankFinal();
new BlankFinal(99);
}
}
class Help{
int h;
public Help(int hh){
this.h = hh;
}
}