在平時寫代碼時,可以自定義泛型類。當使用同一類型的對象時,這是非常有用的,但在實例化類之前,我們不知道它將是哪種類型。
下面讓我們定義一個使用泛型參數的方法。首先,在定義一個類用到泛型時,必須使用特殊語法來支持這種類型。在下面的例子中,<T>
表示定義的類將要使用的類型:
public class MyGeneric<T> {
當然,也可以定義泛型中包含多個類的類型,比如java.util.Map
:
public class MyGeneric<T, U, V> { }
接下來,我們定義一個完整的類,其中包含ArrayList
對象,用來存放'
ArrayList
對象。
import java.util.ArrayList;
public class MyGeneric<T> {
private ArrayList<T> list;
public MyGeneric() {
list = new ArrayList<T>();
}
public void add(T element) {
list.add(element);
}
}
需要注意的是,我們實際上並不是處理一個名為T
的類。相反,T
是用於創建MyGeneric
實例時使用的類型。 Java規范允許使用所需的任何標識符,但標准約定是使用單個大寫字母將其與正常類名稱區分開來。 現在我們已經將add
方法定義為T
類型的參數,只能使用與MyGeneric
實例構造相同的類型。 以下代碼是非法的,並產生編譯錯誤:
MyGeneric<String> rs = new MyGeneric<>();
rs.add(1); // illegal for a MyGeneric<String>
如果要從方法返回泛型類型,則可以將其作為方法簽名的返回類型,定義所示:
SecureRandom random = new SecureRandom();
// 省略其他代碼
public T getRandomElement() {
int index = random.nextInt(list.size());
return list.get(index);
}
getRandomElement
方法返回類型與定義類的類型是一致的。現在,我們就可以使用上面的方法,來構建類型實例。
public static void main(String [] args) {
MyGeneric<String> names = new MyGeneric<>();
names.add("zhangsan");
names.add("lisi");
names.add("wangwu");
names.add("zhaoliu");
// 隨機獲取list的一個元素
String name = names.getRandomElement();
System.out.println(name);
}
對String
類型變量names
的賦值是安全的,我們將始終從getRandomElement
方法獲取一個字符串。 這只是因為我們使用String
類型構造了MyGeneric
實例。 add
和 getRandomElement
方法的定義與構造函數的定義具有相同的類型,編譯器將強制執行此約束。 讓我們嘗試在構造函數中使用不同類型的MyGeneric
類,這次使用我們Integer
類:
MyGeneric<Integer> numbers = new MyGeneric<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
Integer oneNumber = numbers.getRandomElement();
System.out.println(oneNumber);
你可以在需要類處理某些類型的對象(在構建類之前不知道),以及希望編譯器嚴格執行類型限制的情況下定義自己的泛型。這樣做的主要優點是安全和方便。
最后,附上完整的實例代碼:
package wicked.coo;
import java.security.SecureRandom;
import java.util.ArrayList;
/**
*
* @author i324779
*
* @param <T> 自定義泛型
*/
public class MyGeneric<T> {
SecureRandom random = new SecureRandom();
private ArrayList<T> list;
public MyGeneric() {
list = new ArrayList<T>();
}
public void add(T element) {
list.add(element);
}
public T getRandomElement() {
int index = random.nextInt(list.size());
return list.get(index);
}
public static void main(String [] args) {
MyGeneric<String> names = new MyGeneric<>();
names.add("zhangsan");
names.add("lisi");
names.add("wangwu");
names.add("zhaoliu");
// 隨機獲取list的一個元素
String name = names.getRandomElement();
System.out.println(name);
MyGeneric<Integer> numbers = new MyGeneric<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(4);
Integer oneNumber = numbers.getRandomElement();
System.out.println(oneNumber);
}
}