Java 中對於泛型方法的定義:
public <T> T getT(){
.....相關代碼;
}
其中我對<T>的理解就是申明只是一個泛型方法的標記,T是返回的類型。
對於泛型類的定義:
public class Type<T>{
....相關代碼
}
上面寫的是關於泛型方法和泛型類的定義。這里寫這篇博客的主要目的是為了記錄<? extends T> 和 <? super T>的理解。
<? extends T>是上界通配符。邏輯上來說,一個可以往里面放動物的容器,也可以往里面放狗,因為狗是繼承了動物的,所以從
邏輯上來說,一個可以放狗的容器也應該是繼承一個可以放動物的容器的。但是Java中這是不對的。這時候就需要上界通配符來解決這個問題。
可以定義一個Content<? extends Animal> content,這個content容器里面可以放任何Animal包括其子類。這使得容器Content之間也有
了一定的聯系。但是其中的也有一定的副作用。Content類里面有個getContent()方法,這個方法是不會影響使用的。因為對java編譯器來說,
里面所有的東西都有一個相同的父親,那就是Animal。但是如果你想要使用setContent()方法,這時就會出現一個問題,問題是什么呢?那就
是我只知道里面的類型是Animal以及Animal的派生類,但是無法確定具體的類型,是Dog或者Cat等。這里的類型沒有具體給明,所以編譯器
在這里只是給了一個占位符,所以到后面往t里面放Dog或者Apple的時候他都不知道是不是和Animal相匹配,所以這是不允許使用set的。下面
方法中的 public void setContent(List<T> content) 如果想可以set T包括T的子類的List的時候,可以這么定義:
public void setContent(List<?extends T> content)。
<? super T>是下界通配符。其作用這好和上面的<? extends T>相反。Content<? super Animal> content 表示的是Animal 以及Animal
基類的容器,但不是Dog基類的容器。里面的setContent()方法是可以正常使用的。因為它規定了最小粒度的下限,那就是Animal。但是它往外面
getContent()就比較費勁,因為他們公共的基類只有Object。所以取出來的內容只能用Object來裝。
所以這里總結了一點就是如果一個內容他需要set的內容比較多,那就使用<? super T>。如若使用get的多一點,那就使用<? extends T>。
下面是自己定義的一個Content類:
1 package test; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6 7 public class Content<T> { 8 private String contentName; 9 private List<T> content; 10 private T t; 11 private int size; 12 public Content(){ 13 content = new ArrayList<T>(); 14 size = 0; 15 } 16 public String getContentName() { 17 return contentName; 18 } 19 public void setContentName(String contentName) { 20 this.contentName = contentName; 21 } 22 public List<T> getContent() { 23 return content; 24 } 25 @SuppressWarnings("unchecked") 26 public void setContent(List<? extends T> content) { 27 this.content = (List<T>) content; 28 } 29 public void add(T content){ 30 this.content.add(content); 31 } 32 public void getInfo(){ 33 System.out.println(content.toString()); 34 } 35 public int getSize(){ 36 size = content.size(); 37 return size; 38 } 39 public T getT() { 40 return t; 41 } 42 public void setT(T t) { 43 this.t = t; 44 } 45 public void remove(int pos){ 46 this.content.remove(pos); 47 } 48 public T get(int i){ 49 if(i>content.size()) 50 return null; 51 return content.get(i); 52 } 53 }
定義的Animal類:
1 package test; 2 3 public class Animal { 4 private String type; 5 private String describe; 6 public Animal(){ 7 8 } 9 public Animal(String type,String describe){ 10 this.type = type; 11 this.describe = describe; 12 } 13 public String getType() { 14 return type; 15 } 16 public void setType(String type) { 17 this.type = type; 18 } 19 public String getDescribe() { 20 return describe; 21 } 22 public void setDescribe(String describe) { 23 this.describe = describe; 24 } 25 26 }
繼承Animal的Dog類
1 package test; 2 3 public class Dog extends Animal { 4 private String name; 5 private int age; 6 public Dog(String type,String describe,String name,int age){ 7 super(type,describe); 8 this.name = name; 9 this.age = age; 10 } 11 public String getName() { 12 return name; 13 } 14 public void setName(String name) { 15 this.name = name; 16 } 17 public int getAge() { 18 return age; 19 } 20 public void setAge(int age) { 21 this.age = age; 22 } 23 24 }