前言
JDK5.0 引入了泛型概念并改写了Java集合的代码。原先定义集合类不能指明集合类中能存储哪些对象,我们从集合中取数据的时候很容易导致类型转换错误。现在通过定义泛型类,我们在新建一个集合类的时候可以指明集合中存储的数据。编译器会帮助我们检查。
定义泛型类
public class Order<A2> {
String orderName;
int orderId;
A2 orderA2;
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public A2 getOrderA2() {
return orderA2;
}
public void setOrderA2(A2 orderA2) {
this.orderA2 = orderA2;
}
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderA2=" + orderA2 +
'}';
}
// 定义一个泛型方法
public static <T1> void fromArrayToList(T1[] a, Collection<T1> c) {
for (T1 t : a) {
c.add(t);
}
}
}
在上述的代码中我们用A2(字母随意,没有要求。常见的有K,V,T,E等)来声明了一个泛型类。同时也定义了一个泛型方法
测试定义的泛型类
public class OrderTest {
@Test
public void test1(){
// Order是一个泛型类,但是我们不使用泛型。默认用Object
Order order = new Order();
order.setOrderA2("abc");
order.setOrderA2(123);
//既然定义了泛型,那我们就使用泛型
Order<String> order1 = new Order<>();
order1.setOrderA2("abc");
//order1.setOrderA2(1); 编译检查不通过,必须为String类型
Order<Object> object = new Order<>();
Order<Integer> integer = new Order<>();
// object = integer; Order<Object>不能指向Order<Integer>
// 使用通配符来解决上述问题
Order<?> generic = null;
generic = object;
generic = integer;
// 使用通配符只能向其中添加null类型数据,其中拿到的数据为Object
generic.setOrderA2(null);
Object orderA2 = generic.getOrderA2();
// 带限制的通配符
// extends限制范围必须是AbstractList的子类或者其本身 <=
Order<? extends AbstractList> order_1;
// super限制范围必须是ArrayList的父类或其本身
Order<? super ArrayList> order_2;
order_1 = new Order<ArrayList>();//编译通过
// order_1 = new Order<List>() 编译不通过
order_2 = new Order<List>();// 编译通过
order_2 = new Order<ArrayList>();// 编译通过
}
/*测试泛型方法*/
public void test2(){
String[] s = new String[20];
List<String> list1 = new ArrayList<>();
Order.fromArrayToList(s,list1);
Integer[] i = new Integer[10];
List<Integer> list2 = new ArrayList<>();
Order.fromArrayToList(i,list2);
// Order.fromArrayToList(s,list2); 编译失败
}
}
我们定义了泛型类但是我们可以不使用泛型,这样它的默认类型就是Object。注意Object虽然是Integer的父类,但是List<Object>
却不能指向List<Integer>
,通过使用统配符?解决这一问题。注意使用通配符后我们只能向list中添加null,虽然这没有任何意义,从list中获取的数据为Object类型。
子类与父类泛型关系
public class SubOrderTest {
@Test
public void test() {
/*子类不继承父类的泛型*/
SubOrder subOrder = new SubOrder();
subOrder.setOrderA2(1); // 默认类型为Integer
SubOrder1 subOrder1 = new SubOrder1();
subOrder1.setOrderA2(new Object());// 默认类型为Object
/*子类继承父类的泛型*/
SubOrder2<Integer> subOrder2 = new SubOrder2<>();
// 子类继承父类的泛型并扩展父类的泛型
SubOrder3<Integer, String> integerStringSubOrder3 = new SubOrder3<>();
}
}
// 子类不继承父类泛型
class SubOrder extends Order<Integer> {
}
class SubOrder1 extends Order {
}
/* 子类继承父类泛型类*/
class SubOrder2<A2> extends Order<A2> {
}
class SubOrder3<T, A2> extends Order<A2> {
}