//: FinalData.java// The effect of final on fieldsclass Value {int i = 1;}public class FinalData {// Can be compile-time constantsfinal int i1 = 9;static final int I2 = 99;// Typical public constant:public static final int I3 = 39;// Cannot be compile-time constants:final int i4 = (int)(Math.random()*20);static final int i5 = (int)(Math.random()*20);Value v1 = new Value();final Value v2 = new Value();static final Value v3 = new Value();//! final Value v4; // Pre-Java 1.1 Error:// no initializer// Arrays:final int[] a = { 1, 2, 3, 4, 5, 6 };public void print(String id) {System.out.println(id + ": " + "i4 = " + i4 +", i5 = " + i5);}public static void main(String[] args) {FinalData fd1 = new FinalData();//! fd1.i1++; // Error: can‘t change valuefd1.v2.i++; // Object isn‘t constant!fd1.v1 = new Value(); // OK -- not finalfor(int i = 0; i < fd1.a.length; i++)fd1.a[i]++; // Object isn‘t constant!//! fd1.v2 = new Value(); // Error: Can‘t//! fd1.v3 = new Value(); // change handle//! fd1.a = new int[3];fd1.print("fd1");System.out.println("Creating new FinalData");FinalData fd2 = new FinalData();fd1.print("fd1");fd2.print("fd2");}} ///:~由于i1和I2都是具有final屬性的基本數據類(lèi)型,并含有編譯期的值,所以它們除了能作為編譯期的常數使用外,在任何導入方式中也不會(huì )出現任何不同。I3是我們體驗此類(lèi)常數定義時(shí)更典型的一種方式:public表示它們可在包外使用;Static強調它們只有一個(gè);而final表明它是一個(gè)常數。注意對于含有固定初始化值(即編譯期常數)的fianlstatic基本數據類(lèi)型,它們的名字根據規則要全部采用大寫(xiě)。也要注意i5在編譯期間是未知的,所以它沒(méi)有大寫(xiě)。注意對于fd1和fd2來(lái)說(shuō),i4的值是唯一的,但i5的值不會(huì )由于創(chuàng )建了另一個(gè)FinalData對象而發(fā)生改變。那是因為它的屬性是static,而且在載入時(shí)初始化,而非每創(chuàng )建一個(gè)對象時(shí)初始化。fd1: i4 = 15, i5 = 9Creating new FinalDatafd1: i4 = 15, i5 = 9fd2: i4 = 10, i5 = 9
//: BlankFinal.java// "Blank" final data membersclass Poppet { }class BlankFinal {final int i = 0; // Initialized finalfinal int j; // Blank finalfinal Poppet p; // Blank final handle// Blank finals MUST be initialized// in the constructor:BlankFinal() {j = 1; // Initialize blank finalp = new Poppet();}BlankFinal(int x) {j = x; // Initialize blank finalp = new Poppet();}public static void main(String[] args) {BlankFinal bf = new BlankFinal();}} ///:~現在強行要求我們對final進(jìn)行賦值處理——要么在定義字段時(shí)使用一個(gè)表達 式,要么在每個(gè)構建器中。這樣就可以確保final字段在使用前獲得正確的初始化。//: FinalArguments.java// Using "final" with method argumentsclass Gizmo {public void spin() {}}public class FinalArguments {void with(final Gizmo g) {//! g = new Gizmo(); // Illegal -- g is finalg.spin();}void without(Gizmo g) {g = new Gizmo(); // OK -- g not finalg.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);}} ///:~注意此時(shí)仍然能為final自變量分配一個(gè)null(空)句柄,同時(shí)編譯器不會(huì )捕獲它。這與我們對非final自變量采取的操作是一樣的。聯(lián)系客服