可能使用final的三种情况:数据、方法、类。
1.final数据
final 常量必须是基本类型数据,且在定义时须赋值;
一个既是static又是final的域只占据一段不能改变的存储空间,只有一份;(使用全大写字母命名)
当用于对象引用,final使引用只能指向一个对象(实例化一次)。对象本身可以修改。
package chapter7; import java.util.Random; /** * final数据 */ 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; private static final int VALUE_TWO = 99; 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"); // fd1.valueOne++; fd1.v2.i++; fd1.v1 = new Value(9); for (int i = 0; i < fd1.a.length; i++) fd1.a[i]++; // !fd1.v2=new Value(0); // !fd1.VAL_3=new Value(1); // !fd1.a=new int[3]; System.out.println(fd1); System.out.println("Creating new FinalData"); FinalData fd2 = new FinalData("fd2"); System.out.println(fd2); } }
【运行结果】:
fd1: i4 = 15,INT_5 = 18
Creating new FinalData
fd2: i4 = 13,INT_5 = 18
final与static final的区别是:final在一个对象类唯一,static final在多个对象中都唯一。
空白final
需在构造函数中对final赋值
package chapter7; import java.awt.PageAttributes; /** * 空白final */ class Poppet { private int i; Poppet(int ii) { i = ii; } } public class BlankFinal { private final int i = 0; private final int j; 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;
若基类中方法为private时,该方法不是接口的一部分,仅是隐藏于类中的代码。
下面的例子证明,基类中方法为private,导出类中以相同名称生成public等方法,并没有覆盖基类中的方法。
package chapter7; class WithFinal { private final void f() { System.out.println("WithFinal f()"); } private final void g() { System.out.println("WithFinal g()"); } } class OverridingPrivate extends WithFinal { private final void f() { System.out.println("OverridingPrivate f()"); } private final void g() { System.out.println("OverridingPrivate g()"); } } class OverridingPrivate2 extends OverridingPrivate { public final void f() { System.out.println("OverridingPrivate2 f()"); } public final void g() { System.out.println("OverridingPrivate2 g()"); } } public class FinalOverridIllusion { public static void main(String[] args) { OverridingPrivate2 op2 = new OverridingPrivate2(); op2.f(); op2.g(); OverridingPrivate op = op2; // !op.f(); // !o2.g(); WithFinal wf = op2; // !wf.f(); // !wf.g(); } }
【运行结果】:
OverridingPrivate2 f()
OverridingPrivate2 g()
final类
不能继承该类