final根据上下文存在细微的差距,但都是指“这是无法改变的”,一般的理由可能出于两种理由:设计或效率。为了不被误用,有必要辩别一下。
1.带有编译时数值的final基本类型,可作为编译期常量。声明为static表示只有一份(只初始化一次),声明为final,说明是常量不可改变。一般既是static又是final的public类型可理解为全局变量,定义时为全大写,下划线分隔多个单词。
final的引用,意义不是特别大,因为他只代表不能重新指向其它对象,但并不是不能改变引用对象。如下:
final User u = new User();
//u = new User();报错,不可重新指向
u.setId(5); //可以改变对象
数组也是如此,因为数组也是一种引用:
final int[] a = {1,2,3,4};
a[1]++;//可以改变
//a = new int[3];报错,不可重新指向。
空白final,所谓空白final是声明为final,但是又没给定初始值的域。但无论如何,在使用前必须被赋值,这使得final的使用更加灵活,可以根据对象不同而不同,缺又是不可变的。
class Poppet{
private int i;
public Poppet(int i) {
this.i = i;
}
}
public class BlankFinal {
private final int i = 0;
private final int j;//没有下面赋值语句会报错
private final Poppet p;//没有下面赋值语句会报错
public BlankFinal() {
this.j = 1;
this.p = new Poppet(1);
}
public BlankFinal(int x) {
this.j = x;
this.p = new Poppet(x);
}
public static void main(String[] args) {
new BlankFinal();
new BlankFinal(47);
}
}
2.final参数
可以在参数列表中将参数声明为final的,用意是无法在方法中改变引用所指向的对象。
void f(final int i){
//i++;
}
参数可以读,但是不能修改。主要用于向匿名内部类传递参数。
3.final方法
final方法只有一个原因,就是出于设计的考虑,把方法锁定,以防继承类修改方法的行为。private方法会隐式的标位final的,因为子类无法访问它,也无法修改它,手动加上final关键字也没有其它的意义。
4.final类
将类定义为final,即不打算继承,也不打算让其它人继承它。final类中的所有域都隐式的定义为final,无法覆盖,所以再添加final修饰也没有任何意义。
参考《java编程思想》