簡體   English   中英

為什么類型參數必須重復兩次?

[英]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也是通用的,所以通用類型KV被轉發到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<>();}}類型推斷為以下類型之一:

  1. class X <K extends Object , V extends Object> { HashMap<K,V>newInstance(){return new HashMap<>();}}
  2. class X <K extends Object > { < V extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
  3. class X <V extends Object> { < K extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
  4. class X { <K extends Object , V extends Object> HashMap<K,V>newInstance(){return new HashMap<>();}}

另外,如果推斷出類型參數,那么順序是什么。 當明確說明它們時,順序是顯而易見的。 解決推斷的類型參數的順序問題的唯一方法(對我而言很明顯)是它們在代碼中聲明的順序。 但是,如果僅反轉2行代碼的順序(應該無關緊要),則可能會更改破壞構建的公共接口。 好脆!

暫無
暫無

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

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