JAVA開發過程中經常會涉及到跟蹤源碼或查看架構師核心代碼的活動。在覈心代碼或源碼中常見有<T>,<E>,<K,V>,Class<?>,<? extends T> <? super T> 相關的代碼。看起來十分高大上,又不容易看懂,可能會嚇退一些同學。在此做一次整理,並附相應代碼供調試理解。
<T>,<E>,<K,V> 首先這些實際都是泛型中的佔位符,也可以換成A-Z都是可以的。不是一定要寫成這些,也可以A,B,C都是可以的。不過約定俗成的東西方便大家理解,儘量不擅自改動。
在貼錄代碼之前先說明一下相關類的關係
TypeClass類與TypeClass1是並行的兩個演示bean,TypeClassA extends TypeClass, TypeClassB extends TypeClassA
這是基礎的關係,下附相關代碼
package generic.bean;
/**
- 測試Bean類
- @author [email protected]
-
*/
public class TypeClass {private static String key ;
private static String value;
static {
key = "key-TypeClass";
value = "value-TypeClass";
name = "name-TypeClass";
}public int num ;
private static String name;
public void getKey() {
System.out.println("key:"+key);
}
public void getValue() {
System.out.println("value:"+value);
}
public void getName() {
System.out.println("name:"+name);
}
}
package generic.bean;
public class TypeClass1 {
private static String key ;
private static String value;
static {
key = "key-TypeClass1";
value = "value-TypeClass1";
name = "name-TypeClass1";
}
public int num ;
private static String name;
public void getKey() {
System.out.println("key:"+key);
}
public void getValue() {
System.out.println("value:"+value);
}
public void getName() {
System.out.println("name:"+name);
}
}
package generic.bean;
/**
- 測試Bean類,繼承TypeClass
- @author [email protected]
-
*/
public class TypeClassA extends TypeClass {private String typeClassA ;
public void getTypeClassA(){
System.out.println("當前對象類型:"+this.getClass().getSimpleName());
}
}
package generic.bean;
/**
- 測試Bean類,繼承TypeClassA
- @author [email protected]
-
*/
public class TypeClassB extends TypeClassA {private String typeClassB ;
public void getTypeClassB(){
System.out.println("當前對象類型:"+this.getClass().getSimpleName());
}
}
下邊首先是<T>的描述,<T> 主要用來表示類型的泛型,有接口泛型,方法泛型和類的泛型
接口泛型,
package generic.t.interfaces;
/**
- 泛型接口
- @author [email protected]
-
@param <T>
*/
public interface IGenericT<T> {public T getResult() throws InstantiationException, IllegalAccessException;
}
對接口泛型的一種實現,在實現中指定具體的類,ublic class GenericTIImpl implements IGenericT<TypeClass>
package generic.t.interfaces;
import generic.bean.TypeClass;
/**
- 泛型類實現及測試,指定具體類實現
- @author [email protected]
-
*/br/>@SuppressWarnings("rawtypes")
public class GenericTIImpl implements IGenericT<TypeClass>{@Override
public TypeClass getResult() {return new TypeClass();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
IGenericT t = new GenericTIImpl(); TypeClass type = (TypeClass)t.getResult(); type.getKey(); type.getValue(); type.getName();
}
}
對接口泛型的第二種實現,不指定具體的類
package generic.t.interfaces;
import generic.bean.TypeClass1;
/**
- 泛型類實現及測試,不指定具體類實現
- @author [email protected]
-
*/br/>@SuppressWarnings("rawtypes")
public class GenericT1IImpl<T> implements IGenericT<T>{private Class clazz;
public GenericT1IImpl(Class clazz){
this.clazz = clazz;
}@Override
public T getResult() throws InstantiationException, IllegalAccessException {
T t = (T) clazz.newInstance();
return t;
}public static void main(String[] args) throws InstantiationException, IllegalAccessException {
IGenericT t = new GenericTIImpl(); TypeClass1 type = (TypeClass1)t.getResult(); type.getKey(); type.getValue(); type.getName();
}
}
泛型方法與泛型類的實現,該類就是泛型類的實現,其中getT方法根據入參不同,進行了重載,是需要重點關注的部分
package generic.t.classes;
import generic.bean.TypeClass;
import generic.bean.TypeClass1;
/**
- 泛型類示例
- @author [email protected]
-
*/
public class GenericClass<T> {private T t;
public GenericClass(T t){
this.t = t;
}/*
- 使用了泛型的成員方法並不是泛型方法
*/
public T getT(){
return this.t;
}
/*
- 聲明瞭<T>的方法是泛型方法
*/
public <T>T getT(Class<T> tClass){
T tt = null;
try {
tt = tClass.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return tt;
}
public static void main(String[] args) {
//泛型TypeClass的實現 GenericClass<TypeClass> genericClassA = new GenericClass<TypeClass>(new TypeClass()); //泛型TypeClass1的實現 GenericClass<TypeClass1> genericClassB = new GenericClass<TypeClass1>(new TypeClass1()); //調用非泛型方法 TypeClass typeClass = genericClassA.getT(); TypeClass1 typeClass1 = genericClassB.getT(); typeClass.getName(); typeClass1.getName(); //調用泛型方法 typeClass = genericClassA.getT(TypeClass.class); typeClass1 = genericClassA.getT(TypeClass1.class); typeClass.getName(); typeClass1.getName();
}
- 使用了泛型的成員方法並不是泛型方法
}
在泛型實現的潛在規則中。<K,V> 通常表示鍵值對,也就是map<key,value>中的key,value的意思 。 <E> 通常表示集合中的元素。
在下附的代碼中,對 E,K,V 同時進行了實現
package generic.kve;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import generic.bean.TypeClass;
import generic.bean.TypeClass1;
/**
- KVE佔位使用例子
- @author [email protected]
-
*/
public class GenericKVE<K,V,E> {public Map<K,V> map;
public List<E> list;
public GenericKVE(Map<K,V> map) {
this.map = map;
E e = (E) this.map;
this.list = new ArrayList<E>();
this.list.add(e);
}public List<E> getList() {
return this.list;
}public static void main(String[] args) {
Map<TypeClass,TypeClass1> typeMap = new HashMap<TypeClass,TypeClass1>(); typeMap.put(new TypeClass(), new TypeClass1()); GenericKVE kve = new GenericKVE(typeMap); List list = kve.getList(); for(int i=0;i<list.size();i++) { //打印對象類型名稱 System.out.println(list.get(i).getClass().getSimpleName()); Map map = (Map) list.get(i); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Object key = it.next(); //獲取key,也就是k的類型 System.out.println(key.getClass().getSimpleName()); Object val = map.get(key); //獲取value,也就是v的類型 System.out.println(val.getClass().getSimpleName()); } }
}
}
下附執行結果