final关键字:
通常它指的是“这是无法改变的”。
不想做改变可能出于两种理由:设计或效率
使用到final的三种情况:数据、方法和类
1,final数据
许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的。有时数据的恒定不变是很有用的,比如:
1)一个永不改变的编译时常量
2)一个在运行时被初始化的值,而你不希望它被改变
在java中,这类常量必须是基本数据类型,并且以关键字final表示,在对这个常量进行定义的时候,必须赋值。
一个既是static又是final的域只占据一段不能改变的存储空间。
当对象引用而不是基本数据类型运用final时,其含义会有一点令人迷惑。对于基本数据类型,final使数值恒定不变;而用于对象引用,final使引用恒定不变。
一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。
然而,对象其自身却是可以被修改的,java并未提供使任何对象恒定不变的途径(但可以自己编写类以取得使对象恒不变的效果)
这一限制同样适用数组,它也是对象。
A,空白final
java允许生成“空白final”,所谓空白final是指声明为final但又未给定初值的域。
无论什么情况,编译器都确保空白final适用前必须被初始化。但是,空白final在关键字的使用上提供了更大的灵活性。
为此,一个类中的final域就可以做到更加对象而有所不同,却又保持其恒定不变的特性。
// “ blank final fields”
class Poppet{
private int i;
Poppet(int ii){i = ii;}
}
public class BlankFinal{
private final int i = 0;
private final int j ; //Blank final
private final Poppet p;
public BlankFinal(){
j = 1;
p = new Poppet(1);
}
public BlankFinal(int x){
j = x ;
p = new Poppet(x);
public static void main(String[] args){
new BlankFinal();
new BlankFinal(47);
}
}
总结:必须在域的定义处或者每个构造器中用表达式对final进行赋值,这正是final域在使用前总是被初始化的原因所在。
B,final参数
java允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所指向的对象。
这一特性:主要用来向匿名内部类传递数据。
2,final方法
使用final方法的原因有两个:
第一:把方法锁定,以防任何继承类修改它的含义。
第二: 出于设计的考虑,想要确保在继承中使方法行为保持不变,并且不会被覆盖。
final和private关键字:
类中 所有的private方法都隐式地指定为是final的。
3,final类
当将某个类的整体定义为final时,就表明了你不打算继承该类,而且也允许别人这样做。
然而,由于final类禁止继承,所以final类中所有的方法都隐式指定为final的,因为无法覆盖它们。