![](/img/trans.png)
[英]Why do we have to type the class name twice when instantiating a new object in Java?
[英]Why do the type parameters have to be repeated twice?
在Java的此靜態函數中,為什么必須在第1行中重復<K, V>
?
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K, V>();
}
我明白為什么HashMap<K, V>
是必需的,因為該函數返回的HashMap分別具有通用類型K和V作為鍵和值。 但是,為什么函數簽名中的第一個<K, V>
必需的?
為了指示該方法是通用方法,使用/返回通用類型。 如果不存在,則編譯器將查找名為K的具體類型,以及名為V的另一個具體類型。
因為函數newInstance
也是通用的,所以通用類型K和V被轉發到HashMap
。 它的意思是這樣使用:
HashMap<Integer, String> map = newInstance<Integer,String>();
為了增加其他答案,在擦除時所有類型都將丟失。 但是,編譯器首先檢查驗證,這就是為什么需要類型的原因。
這是刪除另一個SO 答案后發生的情況的示例:
但是,使用泛型時,它們會轉換為編譯時檢查和執行時強制轉換。 所以這段代碼:
列表列表= new ArrayList(); list.add(“ Hi”); 字符串x = list.get(0);
被編譯成
列表列表= new ArrayList(); list.add(“ Hi”); 字符串x =(字符串)list.get(0);
編譯器可以合理地推斷類型參數嗎?
在示例情況下為是- static HashMap<K,V>newInstance(){return new HashMap<>();}
顯然是static < K extends Object , V extends Object > HashMap<K,V>newInstance()return new HashMap<K,V>();}
縮寫static < K extends Object , V extends Object > HashMap<K,V>newInstance()return new HashMap<K,V>();}
。
但是,如果您的編譯器推斷出類型參數,那么即使您鍵入錯誤的類名,您的代碼仍然可以編譯。 static void setName ( Sting name )
可能是錯誤的,但是您的編譯器會假設您的意思是<Sting extends Object> static void setName ( Sting name );
通過消除運行時的魔法,它等同於static void setName ( Object name ) ;
。
如果該方法不是靜態的,則推理將成為問題。 class X { HashMap<K,V>newInstance(){return new HashMap<>();}}
類型推斷為以下類型之一:
class X <K extends Object , V extends Object> { HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <K extends Object > { < V extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <V extends Object> { < K extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X { <K extends Object , V extends Object> HashMap<K,V>newInstance(){return new HashMap<>();}}
另外,如果推斷出類型參數,那么順序是什么。 當明確說明它們時,順序是顯而易見的。 解決推斷的類型參數的順序問題的唯一方法(對我而言很明顯)是它們在代碼中聲明的順序。 但是,如果僅反轉2行代碼的順序(應該無關緊要),則可能會更改破壞構建的公共接口。 好脆!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.