下面的程序是不完整的,它缺乏對Enigma的聲明,這個類擴展自java.lang.Object。請為Enigma提供一個聲明,它可以使該程序打印false:
public class Conundrum {
public static void main(String[] args) {
Enigma e = new Enigma();
System.out.println(e.equals(e));
}
}
噢,還有一件事:你不能覆寫equals方法。
乍一看,這似乎不可能實現。因為Object.equals方法將測試對象的同一性,通過Enigma傳遞給equals方法的對象肯定是與其自身相同的。如果你不能覆寫Object.equals方法,那么main方法必然打印true,對嗎?
別那么快下結論,伙計。盡管本謎題禁止你覆寫(override)Object.equals方法,但是你是可以重載(overload)它的,這也就引出了下面的解謎方案:
final class Enigma {
// Don’t do this!
public Boolean equals(Enigma other){
return false;
}
}
盡管這個聲明能夠解決本謎題,但是它的做法確實非常不好的。它違反了謎題58的建議:如果同一個方法的兩個重載版本都可以應用于某些參數,那么它們應該具有相同的行為。在本例中,e.equals(e)和e.equals((Object)e)將返回不同的結果,其潛在的混亂是顯而易見的。
然而,有一種解謎方案是不會違反這項建議的:
final class Enigma {
public Enigma() {
System.out.println(false);
System.exit(0);
}
}
可能會有些爭論,這個解謎方案似乎違背了本謎題的精神:能夠產生我們想要的輸出的println調用出現在了構造器中,而不是在main方法中。然而,它確實解決了這個謎題,你不得不承認它很伶俐。
這里的教訓,可以參閱前面的8個謎題和謎題58。如果你重載了一個方法,那么一定要確保所有的重載版本行為一致。
public class Conundrum {
public static void main(String[] args) {
Enigma e = new Enigma();
System.out.println(e.equals(e));
}
}
噢,還有一件事:你不能覆寫equals方法。
乍一看,這似乎不可能實現。因為Object.equals方法將測試對象的同一性,通過Enigma傳遞給equals方法的對象肯定是與其自身相同的。如果你不能覆寫Object.equals方法,那么main方法必然打印true,對嗎?
別那么快下結論,伙計。盡管本謎題禁止你覆寫(override)Object.equals方法,但是你是可以重載(overload)它的,這也就引出了下面的解謎方案:
final class Enigma {
// Don’t do this!
public Boolean equals(Enigma other){
return false;
}
}
盡管這個聲明能夠解決本謎題,但是它的做法確實非常不好的。它違反了謎題58的建議:如果同一個方法的兩個重載版本都可以應用于某些參數,那么它們應該具有相同的行為。在本例中,e.equals(e)和e.equals((Object)e)將返回不同的結果,其潛在的混亂是顯而易見的。
然而,有一種解謎方案是不會違反這項建議的:
final class Enigma {
public Enigma() {
System.out.println(false);
System.exit(0);
}
}
可能會有些爭論,這個解謎方案似乎違背了本謎題的精神:能夠產生我們想要的輸出的println調用出現在了構造器中,而不是在main方法中。然而,它確實解決了這個謎題,你不得不承認它很伶俐。
這里的教訓,可以參閱前面的8個謎題和謎題58。如果你重載了一個方法,那么一定要確保所有的重載版本行為一致。