一、泛型方法的優點(一)
優點:泛型方法能夠推斷出輸入參數中的參數類型
例:
public <E> E getType(E type){
return type;
}
//當使用該方法的時候,虛擬機能夠推斷出輸入的參數的類型是什麼,並返回該類型。舉例:合併兩個Set列表,用原生類型方法與泛型方法比較
//原生類型方法
public Set union(Set set1,Set set2){
Set set = mew HashSet(s1);
set.addAll(set2);
return set;
}
使用原生類型方法虛擬機會出現類型不安全的警告。//泛型方法
public <E> Set<E> union(Set<E> set1,Set<E> set2){
Set<E> set = new HashSet<E>(set1);
set.addAll(set2);
return set;
}
//由於虛擬機能夠推斷出輸入參數的參數類型,所以E是已知的,不會出現類型不安全的警告。使用:
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> firstSet = new HashSet<String>(
Arrays.asList("Bady","Tim","Alice"));
Set<String> secondSet = new HashSet<String>(
Arrays.asList("Come","On","Go","With","Me"));
Set<String> set = union(firstSet, secondSet);
System.out.println(set);
}
二、泛型的優點(二)
優點:能夠推斷出被賦值對象的類型參數。
例:泛型的靜態工廠方法
public static void main(String[]args){
HashMap<String, String> map = newHashMap();
}
//泛型方法
public static <K,V> HashMap<K,V> newHashMap(){
return new HashMap<K, V>();
}
這就是虛擬機能夠根據被賦值對象的類型參數,推斷出K,V的值是String,String。這樣K,V就是已知類型。我們以前寫含有泛型的容器的時候都是:
HashMap<String,String> hashMap = new HashMap<String,String>();
在new 的時候還需要再重寫一遍類型參數。一個兩個還好,當數量多的時候呢。
所以利用泛型的靜態工廠是一種方便的方法。
三、泛型的優點(三)
優點:能夠推斷出被賦值對象的類型。
是不是跟優點(二)有點像。不過這個是能夠推斷被賦值對象的類型,優點二則是推斷被賦值對象的類型參數,不要弄混了。
例:
在Android中聲明layout中的View到代碼中的時候,都要使用(View)findViewById(R.id.xxx);
就像這樣:Button btn = (Button)findViewById(R.id.xxx);每次有需要強制轉換是一種很繁瑣的事情。
我們可以這樣構建一個方法
public void onCreate(Bundle bundle) {
// TODO Auto-generated method stub
Button btn = getViewById(R.id.xxx);
}
//泛型方法
<span style="white-space:pre"> @SuppressWarnings("unchecked")</span>
public <VT> VT getViewById(int id){
return (VT)findViewById(id);
}
因爲虛擬機能夠推斷出被賦值對象的類型,也就是能夠推斷出VT爲Button類型。這樣VT就是確定的類型,就不會出現類型不安全的問題。這樣就能放心的消除警告了注:優點(二)(三)方法使用的基礎,都是基於賦值給被賦值對象。如果沒有被賦值對象,直接調用方法會發生什麼情況呢?
就像這樣:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setView(getViewById(R.id.main_tv));//報錯
}
//所有Button,等控件都是View的子類。
//作用:將生成的View放入該方法中
public void setView(View view){
View myView = view;
}
public <VT> VT getViewById(int id){
return (VT)findViewById(id);
}
如果沒有被賦值對象,虛擬機就無法進行判斷,返回的類型就是Object,就是說getViewById()返回的是Object。因爲Object != View 所以肯定會出錯
四、有限制的類型參數的特殊形式(遞歸的類型限制)
形式:<E extends Comparable<E>>
表述:可以與自身比較的E類
使用情形:一般用於Comparable類
例:求List容器中的最大值
public <T extends Comparable<T>> T calculateMax(List<T> list){
Iterator<T> iterator = list.iterator();
T result = iterator.next();
while (iterator.hasNext()){
T t = iterator.next();
//需要判斷大小
if (result.compareTo(t) < 0){
result = t;
}
}
return result;
}