對於我的英語不好,我很抱歉,所以我儘可能多地舉例說明。我希望你能理解我的意思。
讓我們舉一個簡單的例子,其中參數類型是一個對象。
String string(Object value){
return value instanceof String ? value : null;
}
上面的例子仍然需要下鑄造以來的value
的引用類型String
是Object
:
String string(Object value){
return value instanceof String ? (String)value : null;
}
和那麼我們擴大與通用參數的例子,你可以通過強制轉換String
來解決T
類型的有界方法表達式語句賦值的地方。並且如果有界的T
不是String
類派生自的類型,則在運行時將投射失敗。以上則實例
<T,R> T string(R value){
// the code cast R to T will generate a compile unchecked warnings.
return value instanceof String ? (T) value : null;
}
// the code is ok on compile stage, but will throw a ClassCastException on runtime.
Date date= string("bad");
// the code is ok both on compile & runtime.
// because a unbounded generic argument which will reference to Object .
string("ok");
基地可以通過鑄造功能Function<T,R>
解決您的代碼:
static <R> Function<A, R> findMapper(Class<R> cls) {
if (cls == B.class) {
return (Function<A, R>) a2bmapper;
}
return null;
}
我們知道泛型參數R
是B
但仍產生一個未檢查的編譯警告由於編譯器不知道。然後我們可以做下面的事情讓編譯器知道它:
static <R> Function<A, R> findMapper(Class<R> cls) {
if (cls == B.class) {
return a2bmapper.getClass().cast(a2bmapper);
}
return null;
}
簡短的答案是類型系統可以檢查很多,但它不能檢查_everything_。侷限性(理論和實踐,就時間和投入到語言規範和編譯器中而言)將發揮作用。在這種情況下,Java不會進行傳遞計算,因爲cls == B.class,R == B – yshavit