簡體   English   中英

getConstructors() 方法的返回 Object 不是參數化類型的數組嗎?

[英]Is the return Object of getConstructors() method not array of parameterized type?

在這個鏈接中,聲明我們不能創建參數化類型的數組。 創建一個 Arraylists 數組

但是在 java 反射中,我們可以調用 getConstructors() 方法並將其返回的對象保存如下。

Constructor<?>[] constructors = MyClass.class.getConstructors();

那么問題來了,不也是參數化類型object嗎?

Constructor<?>[]

如果是,那么為什么它在這里工作?

好問題。 您當然可以通過破壞類型安全來定義參數化類型數組,例如,

ArrayList<Individual> [] group = new ArrayList()[4] //unchecked warning

Arrays 是協變子類型,這意味着Strings []Object []的子類型,其實現方式是在運行時檢查我們添加的元素的類型,例如,

String [] stArr = new String[10]
Object [] objects = strings;
objects[0] = new Integer(); // Runtime ArrayStoreException will be thrown

為了防止錯誤的分配,編譯器會對每個數組分配進行運行時檢查。

而 generics 只是編譯時。 所以 Java 一旦別名為子類型,就無法識別泛型類型,例如,

ArrayList<Integer> [] lstArr = new ArrayList[10];
Object [] objArr= lstArr;
ArrayList<String> strList = new ArrayList<String>();        
objArr[0] = strList; // No runtime exception here

無界通配符類型是唯一的方式,因為在放置元素時,無界通配符類型不需要真正的類型檢查。

ArrayList<?>[] lstArr = new ArrayList<?>[10];
lstArr[0] = new ArrayList<Integer>();

希望這能回答你的問題。

首先,將返回類型聲明為Constructor<?>[]並不意味着創建一個Constructor<?>數組,對嗎? 它只是說“此方法返回此類型”。 只是說不會創建一個數組,所以那里沒有錯誤。

但是getConstructors將在其實現的某個地方創建一個Constructor<?>[] ,對嗎? 這是如何運作的?

好吧,在跟蹤getConstructors的源代碼后,我發現了創建數組的這一行:

Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];

如果Class是一個接口,則執行此行(創建一個空數組)。 (如果Class不是接口,則調用native方法。)為什么可以創建Constructor<?>[]

在這種情況下, Oracle 文檔不是 100% 准確(這並不是說您不再應該信任它),因為Constructor<?>參數化類型,但new Constructor<?>[0]是有效的。

讓我們看看更權威的文檔 - Java 語言規范 - 說關於創建泛型類型的 arrays:

15.10.1。 數組創建表達式

[...]

如果 ClassOrInterfaceType 不表示可具體化類型(第 4.7 節),則為編譯時錯誤。 否則,ClassOrInterfaceType 可以命名任何命名的引用類型,甚至是抽象的 class 類型(第 8.1.1.1 節)或接口類型。

可具體化類型定義為:

4.7 可具體化類型

當且僅當滿足以下條件之一時,類型才是可具體化的:

  • 它指的是非泛型 class 或接口類型聲明。

  • 它是一種參數化類型,其中所有類型 arguments 都是無界通配符(第 4.5.1 節)。

  • [...]

第二個要點適用於Constructor<?> 這就是為什么你可以創建一個new Constructor<?>[10]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM