假設你不能修改前一個謎題(謎題68)中的X和C這兩個類。你能否編寫一個類,其main方法將讀取X.Y類中的Z域的值,然后打印它。注意,不能使用反射。
本謎題初看起來是不可能實現(xiàn)的。畢竟,X.Y類被具有相同名字的一個域給遮掩了,因此對其命名的嘗試將引用到該域上。
事實上,我們是可以引用到一個被遮掩的類型名的,其技巧就是在某一種特殊的語法上下文環(huán)境中使用該名字,在該語法上下文環(huán)境中允許出現(xiàn)一個類型但是不允許出現(xiàn)一個變量。在轉(zhuǎn)型表達式的括號中間的部分就是這樣一種上下文環(huán)境。下面的程序通過使用這種技術解決了這個謎題,并且將打印出我們所期望的Black:
public class FadeToBlack {
public static void main(String[] args){
System.out.println(((X.Y)null).Z);
}
}
請注意,我們是用一個具有X.Y類型的表達式來訪問X.Y類的Z域的。就像我們在謎題48和54中所看到的,用一個表達式而不是類型名來訪問一個靜態(tài)成員是合法的,但卻是一種有問題的用法。
不借助這種有問題的用法,而是通過在一個類聲明的extends子句中使用一個被遮掩的類這種方式,你也可以解決本謎題。因為基類總是一種類型,出現(xiàn)在extends子句中的名字從來都不會被解析為變量名。下面的程序就展示了這項技術,它也會打印出Black:
public class FadeToBlack {
static class Xy extends X.Y{ }
public static void main(String[ ] args){
System.out.println(Xy.Z);
}
}
如果你使用的5.0或更新的版本,那么通過在一個類型變量聲明的extends子句中使用X.Y這種方式,你也可以解決本謎題:
public class FadeToBlack {
public static void main(String[] args){
System.out.println(T.Z);
}
}
總之,要解決由類型被變量遮掩而引發(fā)的問題,需要按照標準的命名習慣來重命名類型和變量,就像在謎題68中所討論的那樣。如果做不到這一點,那么你應該在只允許類型名的上下文環(huán)境中使用被遮掩的類型名。幸運的話,你將永遠不需要憑借這種對程序的變形來解決問題,因為大多數(shù)的類庫作者都很明智,他們都避免了必需使用這種變形的有問題的用法。然而,如果你確實發(fā)現(xiàn)自己身處這種境地,那么你是要了解這個問題需要解決。
本謎題初看起來是不可能實現(xiàn)的。畢竟,X.Y類被具有相同名字的一個域給遮掩了,因此對其命名的嘗試將引用到該域上。
事實上,我們是可以引用到一個被遮掩的類型名的,其技巧就是在某一種特殊的語法上下文環(huán)境中使用該名字,在該語法上下文環(huán)境中允許出現(xiàn)一個類型但是不允許出現(xiàn)一個變量。在轉(zhuǎn)型表達式的括號中間的部分就是這樣一種上下文環(huán)境。下面的程序通過使用這種技術解決了這個謎題,并且將打印出我們所期望的Black:
public class FadeToBlack {
public static void main(String[] args){
System.out.println(((X.Y)null).Z);
}
}
請注意,我們是用一個具有X.Y類型的表達式來訪問X.Y類的Z域的。就像我們在謎題48和54中所看到的,用一個表達式而不是類型名來訪問一個靜態(tài)成員是合法的,但卻是一種有問題的用法。
不借助這種有問題的用法,而是通過在一個類聲明的extends子句中使用一個被遮掩的類這種方式,你也可以解決本謎題。因為基類總是一種類型,出現(xiàn)在extends子句中的名字從來都不會被解析為變量名。下面的程序就展示了這項技術,它也會打印出Black:
public class FadeToBlack {
static class Xy extends X.Y{ }
public static void main(String[ ] args){
System.out.println(Xy.Z);
}
}
如果你使用的5.0或更新的版本,那么通過在一個類型變量聲明的extends子句中使用X.Y這種方式,你也可以解決本謎題:
public class FadeToBlack {
public static
System.out.println(T.Z);
}
}
總之,要解決由類型被變量遮掩而引發(fā)的問題,需要按照標準的命名習慣來重命名類型和變量,就像在謎題68中所討論的那樣。如果做不到這一點,那么你應該在只允許類型名的上下文環(huán)境中使用被遮掩的類型名。幸運的話,你將永遠不需要憑借這種對程序的變形來解決問題,因為大多數(shù)的類庫作者都很明智,他們都避免了必需使用這種變形的有問題的用法。然而,如果你確實發(fā)現(xiàn)自己身處這種境地,那么你是要了解這個問題需要解決。