[英]Java: Generics syntax
這可以返回一個int列表:
public List<Integer> GetIListImpl() {
return new ArrayList<Integer>();
}
但是,如果我想讓調用者指定泛型類型呢? 像這樣的東西,雖然從語法上來說我不知道怎么做:
public List<T> GetIListImpl<T>() {
return new ArrayList<T>();
}
用法是:
List<String> = GetIListImpl<String>();
static
工廠方法 看起來您想要編寫方便的工廠方法來實例化泛型集合。
您可以編寫如下通用方法:
public static <T> List<T> newArrayList() {
return new ArrayList<T>();
}
public static <K,V> Map<K,V> newHashMap() {
return new HashMap<K,V>();
}
然后你可以簡單地寫:
// absolutely type-safe!!! no compilation warnings at all!!!
List<String> names = newArrayList();
List<Integer> nums = newArrayList();
Map<String, List<String>> map = newHashMap();
請注意,在某些上下文中,上述方法不必是static
,您可以選擇從方法中省略實現class
名稱,並僅使用interface
名稱(例如newList
, newMap
)。
這種通用類型推斷static
工廠方法實際上得到了Effective Java 2nd Edition的認可; 它擁有成為本書中討論的第一個項目的獨特特權。
以下是第1項中的相關引用:考慮static
工廠方法而不是構造函數 :
static
工廠方法的第四個優點是它們減少了創建參數化類型實例的詳細程度。當您調用參數化類的構造函數時,遺憾的是您必須指定類型參數,即使它們在上下文中是顯而易見的。 這通常要求您快速連續提供兩次類型參數:
Map<String,List<String>> m = new HashMap<String,List<String>>();
隨着類型參數的長度和復雜性的增加,這種冗余規范很快變得痛苦。 但是,對於
static
工廠,編譯器可以為您計算類型參數。 這稱為類型推斷 。 例如, 假設HashMap
提供了這個static
工廠:public static <K,V> HashMap<K,V> newInstance() { return new HashMap<K,V>(); }
然后你可以用這個簡潔的替代方案替換上面的羅嗦聲明:
Map<String,List<String>> m = HashMap.newInstance();
遺憾的是,自版本1.6起,標准集合實現(如
HashMap
沒有static
工廠方法,但您可以將這些方法放在自己的實用程序類中。 更重要的是,您可以在自己的參數化類中提供此類static
工廠。
該項還規定了這些static
工廠方法的通用命名約定:
getInstance
- 返回參數[...]描述的實例newInstance
- 與getInstance
類似,但它保證返回的每個實例都與其他實例不同。new
Type
- 與newInstance
類似,但在工廠方法位於不同類時使用。Type
表示factory方法返回的對象類型。
在大多數情況下,您不必顯式提供類型參數,因為Java泛型類型推斷系統通常可以找出您需要的內容。
然而,要提供顯式類型參數,語法是將其放在方法名稱之前 (而不是之后 )。 下面是使用顯式參數調用java.util.Collections
的泛型方法<T> List<T> emptyList()
:
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
請注意,泛型方法調用的顯式類型參數化的語法怪癖是您必須限定類型(如果是static
)或您正在調用該方法的對象,即使它們不是顯式參數化也可以省略它們。
應該注意的是, Guava實際上已經為Java Collections Framework中的類型提供了static
工廠方法:
從主要package com.google.common.collect
:
Lists.newArrayList()
, newLinkedList()
,... Sets.newHashSet()
, newTreeSet()
, newEnumSet(…)
,... Maps.newHashMap()
, newTreeMap()
, newEnumMap(…)
,... 實際上,根據Effective Java 2nd Edition的推薦,Guava自己的集合不提供public
構造函數,而是提供static create()
工廠方法:
庫的其余部分還提供了許多非常有用的功能。
語法是
public static <T> List<T> getIListImpl() {
return new ArrayList<T>();
}
你很親密
用法更像是:
MyClass.<Integer>getIListImpl();
首先,您必須在方法上指定泛型類型,而不是類級別。
class Test
{
public static <T> List<T> getListImpl() {
return new ArrayList<T>();
}
}
查看Generic類型參數的位置,它位於方法名稱之前。 對於類,它位於類名后面。 因此,不要在方法名稱之后添加泛型類型,而是像這樣調用它
List<Integer> l = Test.<Integer>getListImpl()
您必須使用類名或實例來調用它。 編譯器不喜歡以下內容:
List<Integer> l = <Integer>getListImpl()
有時它沒有泛型類型
List<Integer> l = getListImpl()
這里的比較類和方法通用
class Test<T>{}//Generic after class name
T<Integer> t = new T<Integer>();
void <T> methName(){}//Generic before method name
t.<Integer>methName();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.