本謎題旨在檢驗當你試圖隱藏一個final域時將要發(fā)生的事情。下面的程序?qū)⒆鲂┦裁茨兀?BR> class Jeopardy {
public static final String PRIZE = "$64,000";
}
public class DoubleJeopardy extends Jeopardy {
public static final String PRIZE = "2 cents";
public static void main(String[ ] args) {
System.out.println(DoubleJeopardy.PRIZE);
}
}
因為在Jeopardy中的PRIZE域被聲明為是public和final的,你可能會認為Java語言將阻止你在子類中重用該域名。畢竟,final類型的方法不能被覆寫或隱藏。如果你嘗試著運行該程序,就會發(fā)現(xiàn)它可以毫無問題地通過編譯,并且將打印2 cents。出什么錯了呢?
可以證明,final修飾符對方法和域而言,意味著某些完全不同的事情。對于方法,final意味著該方法不能被覆寫(對實例方法而言)或者隱藏(對靜態(tài)方法而言)[JLS 8.4.3.3]。對于域,final意味著該域不能被賦值超過一次[JLS 8.3.1.2]。關鍵字相同,但是其行為卻完全不相關。
在該程序中,final域DoubleJeopardy.PRIZE隱藏了final域Jeopardy.PRIZE,其凈損失達到了$63,999.98。盡管我們可以隱藏一個域,但是通常這都是一個不好的念頭。就像我們在謎題66中所討論的,隱藏域可能會違反包容性,并且會混淆我們對類型與其成員之間的關系所產(chǎn)生的直覺。
如果你想保證在Jeopardy類中的獎金可以保留到子類中,那么你應該用一個final方法來代替final域:
class Jeopardy {
private static final String PRIZE = "$64,000";
public static final String prize() {
return PRIZE;
}
}
對語言設計者來說,其教訓是應該避免在不相關的概念之間重用關鍵字。一個關鍵字應該只在密切相關的概念之間重用,這樣可以幫助程序員構建關于易混淆的語言特性之間的關系的印象。在Java的final關鍵字這一案例中,重用就導致了混亂。應該注意的是,作為一種有年頭的語言來說,在無關的概念之間重用關鍵字是它的一種自然趨勢,這樣做可以避免引入新的關鍵字,而引入新的關鍵字會對語言的穩(wěn)定性造成極大的損害。當語言設計者在考慮該怎么做時,總是在兩害相權取其輕。
總之,要避免在無關的變量或無關的概念之間重用名字。對無關的概念使用有區(qū)別的名字有助于讓讀者和程序員區(qū)分這些概念。
public static final String PRIZE = "$64,000";
}
public class DoubleJeopardy extends Jeopardy {
public static final String PRIZE = "2 cents";
public static void main(String[ ] args) {
System.out.println(DoubleJeopardy.PRIZE);
}
}
因為在Jeopardy中的PRIZE域被聲明為是public和final的,你可能會認為Java語言將阻止你在子類中重用該域名。畢竟,final類型的方法不能被覆寫或隱藏。如果你嘗試著運行該程序,就會發(fā)現(xiàn)它可以毫無問題地通過編譯,并且將打印2 cents。出什么錯了呢?
可以證明,final修飾符對方法和域而言,意味著某些完全不同的事情。對于方法,final意味著該方法不能被覆寫(對實例方法而言)或者隱藏(對靜態(tài)方法而言)[JLS 8.4.3.3]。對于域,final意味著該域不能被賦值超過一次[JLS 8.3.1.2]。關鍵字相同,但是其行為卻完全不相關。
在該程序中,final域DoubleJeopardy.PRIZE隱藏了final域Jeopardy.PRIZE,其凈損失達到了$63,999.98。盡管我們可以隱藏一個域,但是通常這都是一個不好的念頭。就像我們在謎題66中所討論的,隱藏域可能會違反包容性,并且會混淆我們對類型與其成員之間的關系所產(chǎn)生的直覺。
如果你想保證在Jeopardy類中的獎金可以保留到子類中,那么你應該用一個final方法來代替final域:
class Jeopardy {
private static final String PRIZE = "$64,000";
public static final String prize() {
return PRIZE;
}
}
對語言設計者來說,其教訓是應該避免在不相關的概念之間重用關鍵字。一個關鍵字應該只在密切相關的概念之間重用,這樣可以幫助程序員構建關于易混淆的語言特性之間的關系的印象。在Java的final關鍵字這一案例中,重用就導致了混亂。應該注意的是,作為一種有年頭的語言來說,在無關的概念之間重用關鍵字是它的一種自然趨勢,這樣做可以避免引入新的關鍵字,而引入新的關鍵字會對語言的穩(wěn)定性造成極大的損害。當語言設計者在考慮該怎么做時,總是在兩害相權取其輕。
總之,要避免在無關的變量或無關的概念之間重用名字。對無關的概念使用有區(qū)別的名字有助于讓讀者和程序員區(qū)分這些概念。

