final关键字
可能使用到final的三种情况:数据、方法和类。
1. final 数据
1.一个永不改变的编译时变量
2.一个在运行时被初始化的值,而不能被改变
一个既是static 又是final的域只占一段不能改变的存储空间。
对于基本类型,final使数值恒定不变;
而对于对象引用,一旦引用被初始化指向一个对象,就无法把它改为指向另一个对象,然而对象自身却是可以修改的。
一个既使用final 有使用static final的例子
class SelfControl{
private static int counter;
private int id=counter++;
public String toString(){
return "SelfControl "+id;
}
}
class WithStaticFields{
final SelfControl sc=new SelfControl();
static final SelfControl ssc=new SelfControl();
public String toString(){
return "sc= "+sc+"\n"+"ssc"+ssc;
}
}
public class FinalFields {
public static void main(String[] args){
System.out.println("first object");
System.out.println(new WithStaticFields());
System.out.println("second object");
System.out.println(new WithStaticFields());
}
}
运行结果:
first object
sc= SelfControl 1
ssc= SelfControl 0
second object
sc= SelfControl 2
ssc= SelfControl 0
final :在一个对象类唯一;
static final:在多个对象中都唯一;
空白final
是指被声明为final但未给定初始值的域。编译器一定要保证空白final在使用之前一定被初始化。可以在构造器中或者调用this()进行初始化,否则编译器报错。使用空白final,一个类中的final域可以做到根据对象的不同而有所不同,但又保持其恒定不变的特性。
class Poppet {
private int i;
Poppet(int ii) { i = ii; }
}
public class BlankFinal {
private final int i = 0; // Initialized final
private final int j; // Blank final
private final Poppet p; // Blank final reference
// Blank finals MUST be initialized in the constructor:
public BlankFinal() {
j = 1; // Initialize blank final
p = new Poppet(1); // Initialize blank final reference
}
public BlankFinal(int x) {
j = x; // Initialize blank final
p = new Poppet(x); // Initialize blank final reference
}
public static void main(String[] args) {
new BlankFinal();
new BlankFinal(47);
}
}
final 参数
在参数列表中将参数指明为final,将无法在方法中更改参数引用所指向的对象。
class Gizmo {
public void spin() {}
}
public class FinalArguments {
void with(final Gizmo g) {
//! g = new Gizmo(); // Illegal -- g is final
}
void without(Gizmo g) {
g = new Gizmo(); // OK -- g not final
g.spin();
}
// void f(final int i) { i++; } // Can't change
// You can only read from a final primitive:
int g(final int i) { return i + 1; }
public static void main(String[] args) {
FinalArguments bf = new FinalArguments();
bf.without(null);
bf.with(null);
}
}
2. final 方法
对方法使用final,确保在继承中,使方法的行为不会改变,并且不会被覆盖。
3. final 类
final 类表明该类不能被继承,final类中的方法都被隐式指定为final,因此无法覆盖。