一、定义泛型类
public class Order<T> {
String orderName;
int orderId;
T orderT;
public Order(){}
public Order(String orderName,int orderId,T orderT)
{
this.orderName=orderName;
this.orderId=orderId;
this.orderT=orderT;
}
public T getOrderT()
{
return orderT;
}
public void setOrderT(T orderT)
{
this.orderT=orderT;
}
}
public void test()
{
Order order=new Order();
order.setOrderT("ABC");
order.setOrderT(123);
Order<String> order1=new Order<String>();
}
二、子类继承
情况1:
public class SubOrder extends Order<Integer>{
}
@Test
public void test2()
{
SubOrder subOrder=new SubOrder();
subOrder.setOrderT(11);
}
情况2:子类仍是泛型类
public class SubOrder<T> extends Order<T>{
}
SubOrder<String> sub2=new SubOrder<>();
sub2.setOrderT("order2");
三、细节补充
- 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内,比如
<E1,E2,E3> - 泛型类的构造器
public GenericClass(){} 也就是说声明构造器的时候不用加泛型的尖括号 - 实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致
- 泛型不同的引用不能相互赋值
尽管在编译时ArrayList<String> 和ArrayList<Integer> 是两种类型,但是,在运行时只有一个ArrayList被加载到JVM中 - 泛型如果不指定,将被擦除,泛型对应的类型均按照object处理,但不等价与Object。经验:泛型要使用就一路使用;不使用就一路不使用
- 泛型的指定中不能使用基本数据类型,可以使用包装类替换。
- 静态方法不能用泛型–生成对象的时候才指定类型呢
- 异常类不能是泛型的
- 不能使用new E[],但是可以
E[] elements=(E[])new Object[capacity];
四、泛型方法
在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系 换句话说,泛型方法所属的类是不是泛型类没有关系
如果这样写: public List<E> copyFromArrayToList(E[] arr) 会认为E是某个类的名字
如果想要把E看作是泛型参数(可以任意指定的数据类型的话), 这样写: public <E> List<E> copyFromArrayToList(E[] arr)
public <E> List<E> copyFromArrayToList(E[] arr)
{
ArrayList<E> list=new ArrayList<>();
for(E e:arr)
{
list.add(e);
}
return list;
}
测试:当arr类型确定的时候,就由此确定返回值的类型。这个E是在调用的时候确定的,而不是实例化的时候确定的,也就可以指定为静态方法了
@Test
public void Test3()
{
Order<String> order=new Order<>();
Integer[] arr=new Integer[]{1,2,3,4};
List<Integer> list=order.copyFromArrayToList(arr);
System.out.println(list);
}
五、使用通配符
通配符:?
类A是类B的父类,G<A> 和G<B> 是没有关系的,二者的共同父类是G<?>
List<String> list1=new ArrayList<>();
list1.add("123");
list1.add("456");
List<?> list=list1;
Object o=list.get(0);
System.out.println(o);
List<? extends Person> list1=null;
List<? super Person> list2=null;
List<Student> list3=null;
list1=list3;
|