Java中, 經常會碰到這樣一個設計, 一個類需要外部傳入一個List<Shape> 泛型List屬性, 這樣就可以在不同使用場景中傳入不同的List, 可能會傳入 List<Circle>, 也可以會傳入 List<Rect>.
雖然Circle 類是Shape類的子類, 但 List<Circle> 卻不是 List<Shape> 的子類, 所以普通類是不能直接真支持List<T>屬性的, 下面是一個變通的方法, 另一個是將這個普通類改造成泛型類.
下面是普通類支持List<T>屬性的方法, 核心做法是:
1. setter 采用 Object[] 傳入數據;
2. 在返回List<T>的方法中, 需要傳入一個T[].class 類型參數, 這樣能直接返回List<T> data.
⒊ 為了能讓這個普通類知道List<T>每個元素的具體類型, 再增加一個 setter
package test; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Test { public static void main(String[] args) throws IOException { //准備List<T> 數據 List<String> myList=new ArrayList<String>(); myList.add("abc"); ListTProcessor processor=new ListTProcessor(); //將List<T>轉成數組形式, set到ListTProcessor目標對象中 processor.setMyListData(myList.toArray()); processor.setMyItemClazz(String.class); //從ListTProcessor獲取原來的List<T>, 需要傳入 Circle[].class List<String> myList2=processor.getMyList(String[].class); System.out.println(myList2.get(0)); System.in.read(); } } /** * 包含List<T> */ class ListTProcessor { private Object[] myListData; private Class myItemClazz ; public Class getMyItemClazz() { return myItemClazz; } /** * 傳入 List 中每個元素的類型, 以便在 ListTProcessor 隨時知道元素類型 * @param myItemClazz */ public void setMyItemClazz(Class myItemClazz) { this.myItemClazz = myItemClazz; } public Object[] getMyListData() { return myListData; } /** * 以 Object[] 的方式, 將 List<T>的內容存入 * @param myListData */ public void setMyListData(Object[] myListData) { this.myListData = myListData; } /** * 獲取List<T> * @param clazz, 需要將T[].class 類型傳入, 比如 Circle[].class */ public <T> List<T> getMyList(Class<? extends T[]> clazz) { //將object[] 轉成 T[] 數組 T[] array1 = Arrays.copyOf(myListData, myListData.length, clazz); List<T> lst = Arrays.asList(array1); return lst; } }