供應類型有明顯的javac和Eclipse之間存在一些差異。但是,這裏的主要觀點是javac在發佈錯誤時是正確的。最終,您的代碼會將一個Maybe <BarExtendsFoo>轉換爲有風險的Maybe <Foo>。
這裏的訪問()方法的重寫:
public static <TV, TG extends TV> Maybe<TV> something(final TG value) {
return new Maybe<TV>(value);
}
public static class Foo { }
public static class BarExtendsFoo extends Foo { }
public Maybe<Foo> visit() {
Maybe<BarExtendsFoo> maybeBar = something(new BarExtendsFoo());
Maybe<Foo> maybeFoo = maybeBar; // <-- Compiler error here
return maybeFoo;
}
這改寫實際上等同於你的代碼,但它明確地說明你想從也許<使BarExtendsFoo >到也許<富分配>。這是有風險的。事實上,我的Eclipse編譯器在作業行上發佈了一個錯誤。下面是一段代碼來利用這個風險來存儲也許<字符串>對象內部的整數:
public static void bomb() {
Maybe<String> maybeString = new Maybe<String>("");
// Use casts to make the compiler OK the assignment
Maybe<Object> maybeObject = (Maybe<Object>) ((Object) maybeString);
maybeObject.set(new Integer(5));
String s = maybeString.get(); // Runtime error (classCastException):
// java.lang.Integer incompatible with
// java.lang.String
}
工作示例而不非標註釋和缺課將使它更容易爲人們提供幫助。 – 2010-01-11 09:42:39
我有一個簡單的問題......編譯器如何知道你想在調用中返回的實際類型:'Maybe.something(new BarExtendsFoo())'? – 2010-01-11 09:48:04
爲什麼不是 public @Nonnull也許<?延伸Foo> visit(){...} ? – 2010-01-11 09:49:27