public class Book<T extends Comparable & Serializable> implements Serializable{
private T first;
private T second;
}
擦除后:
//类的名字还原为原始类的名字
public class Book implements Serializable{
//泛型变量擦除后,按规则替换为对应的原始类型名字
private Comparable firt;
private Comparable second;
}
如果调整顺序为:
super Book>//指定下限(超类型限定);安全写,指可安全写入Book,以及Book的子类;因为限定最低泛型类型是Book类型
extends Book>//指定上限(子类型限定);安全读,指可把读取的值赋值给Book;因为限定读取到值的最高类型是Book类型,即是Book或Book的子类型
? obj;//error.'?'不能作为一种类型
//类型查询只适用于原始类型,故下面的示例都错误
if(b instanceof BookStore)//error
if(b instanceof BookStore)//error
//warinning->实际转换为了BookStore原始类型
BookStore book = (BookStore)b;
/***.getClass()方法也是返回的是原始类型。**/
BookStore aritBook = new BookStore<>();
BookStore mathBook = new BookStore<>();
if(aritBook.getClass().equals(mathBook.getClass())) {
//都是得到原始类型,故一定是相等的。
}
捕获或抛出泛型变量实例。
obj = new T();//error
private static T obj;//error
try{...}
catch(T e)//error
{
}
代码示例
泛型类:
/** * @author gao tianci * @version $Id: Pair.java, v 0.1 2017年8月13日 上午11:11:55 gao tianci Exp $ * * 泛型类:具有一个或多个类型变量的类。 * 声明: 声明泛型。(一个类型变量T,用尖括号<>括起来,放在类名后面。可以有多个类型变量,eg:BookStore。) * 类型变量:T 代表泛型的类型变量。形式上使用大写字母。用具体类型进行替换,就可以实例化泛型类型。 * 类中定义的泛型类型变量意义:泛型类的类型变量T,可以是该类某个成员方法的返回类型,以及域或是局部变量类型。 */
public class BookStore<T> {
//T 泛型类型变量作为域变量类型
private T first;
private T second;
/** * 构造器 */
public BookStore() {
super();
first = null;
second = null;
}
/**构造器 * T 泛型类型变量作为成员方法的局部变量类型 * @param first * @param second */
public BookStore(T first, T second) {
super();
this.first = first;
this.second = second;
}
//T 泛型类型变量作为成员方法的返回类型
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
public void setFirst(T first) {
this.first = first;
}
public void setSecond(T second) {
this.second = second;
}
}
通用泛型方法工具类
import java.util.Collection;
import org.apache.commons.collections4.CollectionUtils;
/** * @author gao tianci * @version $Id: BookStoreUtil.java, v 0.1 2017年8月14日 下午12:42:24 gao tianci Exp $ */
public class BookStoreUtil {
/** * @param b * @return */
public static boolean hasNulls(BookStore> b) {
return b.getFirst() == null || b.getSecond() == null;
}
/** * @param b */
public static void swap(BookStore> b) {
swapHelper(b);
}
/** * 泛型方法 * @param b */
public static void swapHelper(BookStore b) {
T t = b.getFirst();
b.setFirst(b.getSecond());
b.setSecond(t);
}
/** * 向参数个数可变的方法,传递一个泛型类型实例。 * 实际args是一个泛型数组。虚拟机也必须对应建立一个泛型数组。泛型对此有所放松。会给出一个警告。可使用@SafeVarargs标注。 * @param collection * @param args * @return */
@SafeVarargs
public static Collection addAll(Collection collection, T... args) {
if (CollectionUtils.isNotEmpty(collection) && args.length > 0) {
//添加
for (T item : args) {
collection.add(item);
}
return collection;
}
return null;
}
}
测试类
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/** * @author gao tianci * @version $Id: Test.java, v 0.1 2017年8月15日 下午12:24:46 gao tianci Exp $ */
public class Test {
@org.junit.Test
public void test1() {
@SuppressWarnings("unchecked")
/** * 创建泛型数组。 * 直接创建不允许。 * BookStore[] books = new BookStore[2];///error * 可声明通配类型数组,然后进行类型转换。从而达到创建泛型数组。 * 建议最好使用:ArrayList 集合来满足泛型数组的需求。 */
BookStore[] books = (BookStore[]) new BookStore>[2];
books[0] = new BookStore<>("1", "2");
books[1] = new BookStore<>("3", "4");
//泛型数组转换为对应的List集合
List> arrays = Arrays.asList(books);
arrays.forEach(item -> System.out.println(item.getFirst() + "," + item.getSecond()));
System.out.println("---------");
}
@org.junit.Test
public void test2() {
Collection> collection = new ArrayList<>();
collection.add(new BookStore<>("lala", "la"));
@SuppressWarnings("unchecked")
BookStore[] books = (BookStore[]) new BookStore>[2];
books[0] = new BookStore<>("gaga", "ga");
books[1] = new BookStore<>("haha", "ha");
Collection> resultCollection = BookStoreUtil.addAll(collection, books[0], books[1]);
resultCollection.forEach(item -> System.out.println(item.getFirst() + "," + item.getSecond()));
}
}
测试结果
1,2
3,4
------
lala,la
gaga,ga
haha,ha