[英]What is the benefit of using Class<?> instead of Class as a method parameter type?
注意:這不是我已經在下面鏈接到的問題的重復項。 很明顯,我在發布之前先閱讀了該問題/答案,但沒有以任何形式回答我的問題。
這個鏈接的問題確實更詳細地解釋了為什么通用類存在。 但是,在我遇到的情況下,我沒有得到關於班級收益的專門答案。
我編寫了一個實用程序方法,該方法接受Class類型的參數'cl'並通過使用cl.isInstance(objectInstance)
方法執行邏輯。
但是我看過使用通用通配符Class<?>
聲明參數的示例代碼。
為什么不使用沒有通用通配符的Class? 類不能代表所有可能的類類型,包括泛型嗎? 如果在我的情況下使用Class<?>
什么好處?
現有相關問題(請參閱下文)中接受的答案實際上並沒有提供有用的答案。
主要區別在於代碼對讀者的(自)文檔化。 聲明為Class<?>
變量表示:“此Class
實例表示的實際類型在編譯時未知或無法表示,我知道。” 相比之下, Class
類型說:“我在這里不使用泛型”,也許是因為您不知道Class
是泛型的,或者您有點草率,所以不理解Class<?>
和Class
之間的區別,或者這是非常古老的前泛型代碼。
這對代碼的后果。 例如
Class<?> unknownType=Object.class;
Class<String> string=unknownType;
當您將顯式未知類型分配給聲明已知類型的變量時,會產生編譯時錯誤。
相反
Class nonGenericType=Object.class;
Class<String> string=nonGenericType;
當您執行非通用(也稱為未經檢查 )操作時,只會產生(可抑制)警告。
關於可以對Class
對象執行的操作,除了賦值外,沒有什么區別,因為當您使用它創建新實例時,返回引用的編譯時類型將是java.lang.Object
最抽象的類型java.lang.Object
兩種情況下均為java.lang.Object
。 如果Class
方法接收與type參數相關的參數,則會出現差異,因為您無法為未知類型Class<?>
調用此類方法(這與嘗試將元素插入List<?>
),而您可以在未經處理的Class
實例上未經檢查地調用這種方法。 但是因為沒有這樣的方法,所以Class<?>
和Class
之間在功能上沒有區別。
盡管如此,您仍應始終使用Class<?>
來確保不會發生意外的未經檢查的操作(如上述分配)。 如果使用Class
不會產生編譯器警告,則應檢查如何(重新)啟用它們。 如果編譯器無聲地忽略原始類型或未經檢查的操作,則可能存在其他問題,而Class
以外的其他類型則隱藏在某個地方。
在這種特殊情況下,通配符類型<?>
和原始類型之間的區別僅在於編譯器是否會警告您。 否則它們是等效的,因此,如果由於某種原因您不想使用<?>
語法並且您不關心編譯器警告,則可以使用原始類型而不會出現任何問題。
Netbeans不抱怨原始類型是不正確的行為,而我的Eclipse在使用raw Class
時會抱怨。
Class
對象具有不同的用法模式,這會影響類型是具體類型(在方法參數中顯示為Class<T> clazz
)還是通配符Class<?>
。
API中最常見的形式是具體類型,因為它允許您以類型安全的方式(主要)使用newInstance()
(使所有Class<T>
對象自動成為類型安全的工廠),例如: :
public static void List<T> fill(Class<T> clazz, int size) {
List<T> l = new ArrayList<T>();
for(int i = 0;i < size; i++)
l.add(clazz.newInstance());
return l;
}
所以Class<T>
是有用的,但是Class<?>
呢? 好吧,不是很多。 如開頭所述,語法符合性只是必需的。 另一種選擇是冗余使用具體的T
類型。
public void foo(Class<?> clazz) {
// Do something non-typed, we don't have a type
}
與
public <T> void foo(Class<T> clazz) {
// Do something non-typed, even though we have a type T
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.