我對上界了解清楚,但對下界并不完全了解。例如我有這個代碼:
public class Main<T> {
private T t;
public Main(T t) {
this.t = t;
}
private static class Base {}
public static void main(String[] args) {
Main<? super Base> main = new Main<>(new StringBuilder());
System.out.println(main.t.getClass());
}
}
為什么編譯程序中沒有錯誤盡管StringBuilder不是Base. 因為我認為提供不相關的型別是非法的(我知道t在型別推斷之后不可能將非子類分配給)。它也適用于集合,這是否意味著集合可能不存盤子類,沒有超類Base?請不要將我鏈接到 PECS 問題,我已經閱讀了很多。
uj5u.com熱心網友回復:
編輯:我看到@markspace 的答案幾乎相同并且在此之前發布的有點晚了。由于不同的解釋風格,我僅在此處保留這一點,僅此而已。
這應該是由于菱形運算子的<>原因,它基于最可能的路由進行自動推理,在這種情況下是建構式引數。
我找不到菱形運算子的官方描述,但各種來源對其效果進行了描述 - Java 編譯器在給定菱形運算子功能確定與呼叫匹配的最合適的建構式宣告時進行型別推斷。
如果您將宣告更改為GenericsSuper<? super Base> main = new GenericsSuper<StringBuilder>(new StringBuilder())您將得到預期的錯誤。
沒有這個明確的宣告,<>導致<Object>由于super限制,因此任何事情都是允許的,因為:
- 中的代碼
GenericsSuper沒有問題StringBuilder。它只是想要T. Base與StringBuilderin有一個共同的 superObject。
uj5u.com熱心網友回復:
我將添加它作為實際答案。
我認為<T>這里是 Object,它是 Base 和 StringBuilder 的合法超型別。你這樣做/思考這個的方式基本上是有缺陷的。查看此問題的答案(忽略 PECS 的重復文本):
<? 之間的區別 超級 T> 和 <? 在 Java 中擴展 T>
請注意接受的答案給出的示例,尤其是帶有<Object>以下內容的示例:
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
由于您允許菱形運算子“找出” 的型別T,因此它會“找出”Object有效并使用它。未經測驗,但檢查這是否也編譯:
Main<? super Base> main = new Main<Object>(new StringBuilder());
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/370266.html
上一篇:如何將C 模板實體傳遞給函式?
下一篇:轉換為任意版本的泛型類
