我目前真的無法理解這里發生的事情。我有以下(最小)代碼:
public class SillyCast {
interface B {}
interface D<T extends B> {}
class C<T extends D<?>> {}
class A<T extends B> extends C<D<T>> {}
List<Class<? extends C<?>>> list = new ArrayList<>();
void m() {
list.add((Class<? extends C<?>>) A.class);
}
}
在 Eclipse 中編譯(和運行)此代碼時,一切都按預期作業,但是從命令列(Oracle JDK)執行此操作時,在編譯期間出現以下錯誤:
error: incompatible types: Class<A> cannot be converted to Class<? extends C<?>> list.add((Class<? extends C<?>>) A.class);
我知道 Oracle JDK 的行為并不總是與 Eclipse JDT 完全相同,但這似乎很奇怪。
如何將 的實體添加A.class到我的 ArrayList 中?直覺上似乎這應該是可能的。
為什么 Oracle JDK 和 Eclipse JDT 對這個演員表有不同的看法?為什么 Oracle JDK 在執行此轉換時會出現問題。
起初我認為這可能是一個錯誤,但我在不同的 Java 版本(8 和 11)上對此進行了測驗,問題發生在所有版本上。此外,這種型別的演員似乎太“簡單”了,因為這可能會在多個版本中被忽視,所以期望這是通過設計來完成的。
uj5u.com熱心網友回復:
不確定您要實作的目標,但這很好用:
public class Main{
static interface B {}
static interface D<T extends B> {}
static class C<T extends D<?>> {}
static class A<T extends B> extends C<D<T>>{}
static List<Class<? extends C>> list = new ArrayList<>();
public static void main(String[] args) {
list.add(A.class);
list.add(C.class);
}
}
這真的很令人困惑,你想達到什么目的?您正在通過擴展其他介面的介面進行引數化(然后通過擴展由介面擴展介面引數化的類的類)。這種復雜程度表明它可能需要一種不同的、更簡單的方法:D
編輯:這對你有用嗎?(這編譯和運行沒有錯誤):
public static void main(String[] args) {
List<Class<? super A<?>>> list = new ArrayList<>();
list.add(A.class);
list.add(C.class);
}
我可能錯了,這有點令人困惑,但據我所知C<?>是 的超類C<D<T>>,因此List<? extends C<?>>接受型別的物件C<?>及其所有子項(C由任何型別引數化的變體T),這就是為什么A在其中粘貼實體會出錯的原因.
A作為 的子類C對List<A>and沒有影響List<C>,它們唯一的關系是它們是 List<?> 的子類。
這就是為什么我認為我們一直A遇到錯誤的原因,而is a C<D<T>>,List<A>與List<C>. 我同意如果保留這種關系會感覺很直觀。
uj5u.com熱心網友回復:
我認為正如@ferrouskid 指出的那樣,這不起作用的原因可能是,盡管通常假設,C<?>它不是C<D<?>>.
盡管這更像是一種混淆策略而不是真正的解決方案,但我目前的解決方法是通過A.class在強制轉換之前將變數分配給變數來分散 Oracle 編譯器的注意力(可能需要一個@SuppressWarnings("unchecked"))
Class<?> aa = A.class;
list.add((Class<? extends C<?>>) aa);
免責宣告:這種操作非常危險,因為轉換可能會在運行時失敗。因此,僅當您對受影響的方法具有完整的測驗覆寫率時才執行此操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/388395.html
