jdk 5新特性
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 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 T getOrderT() { return orderT; } public void setOrderT(T orderT) { this.orderT = orderT; } }
@Test public void test1(){ //如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型 //要求:如果大家定义了类是带泛型的,建议在实例化时要指明类的泛型 Order order = new Order(); order.setOrderT(123); order.setOrderT("tom"); //建议:实例化时指明类的泛型 Order<String> order1 = new Order<>("orderName", 1001, "Order的描述"); order1.setOrderT("啊啊啊"); }
注意点:
泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1, E2, E3>
实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。
泛型不同的引用不能相互赋值。
@Test public void test4(){ ArrayList<String> list1 = null; ArrayList<Integer> list2 = new ArrayList<>(); //泛型不同的引用不能相互赋值 // list1 = list2; }
泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价 于Object。经验:泛型要使用一路都用。要不用,一路都不要用。
如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态 属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型。
异常类不能是泛型的
泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系;泛型方法可以声明为静态的。
//泛型方法所属的类是不是泛型类都没有关系 public <E> List<E> copyFromArrayToList(E[] arr){ ArrayList<E> list = new ArrayList<>(); for (E e : arr) { list.add(e); } return list; }
//测试泛型方法 @Test public void test4(){ Order<String> order = new Order<>(); Integer[] arr = new Integer[]{1,2,2,4}; //泛型方法在调用时,指明泛型参数的类型 List<Integer> list = order.copyFromArrayToList(arr); System.out.println(list); }
虽然类A是类B的父类,但G 和 G 不具有子父类关系,二者是并列关系
补充:类A是类B的父类,A
@Test public void test1(){ Object obj = null; String str = null; obj = str; Object[] arr1 = null; String[] arr2 = null; arr1 = arr2; List<Object> list1 = null; List<String> list2 = null; //此时的 list1 和 list2 不具有子父类关系 // list1 = list2; } @Test public void test2(){ AbstractList<String> list1 = null; List<String> list2 = null; ArrayList<String> list3 = null; list1 = list3; list2 = list3; }
通配符:?
类A是类B的父类,G 和 G 是没有关系的,二者的共同父类是G<?>
@Test public void test3(){ List<Object> list1 = null; List<String> list2 = null; List<?> list = null; list = list1; list = list2; print(list1); print(list2); } public void print(List<?> list){ Iterator<?> iterator = list.iterator(); while (iterator.hasNext()){ Object next = iterator.next(); System.out.println(next); } }
@Test public void test3(){ List<Object> list1 = null; List<String> list2 = null; List<?> list = null; list = list1; list = list2; // List<String> list3 = new ArrayList<>(); list3.add("AA"); list3.add("BB"); list3.add("CC"); list = list3; //添加(写入) //对于List<?>就不能向其内部添加数据了。除了添加null以外 list.add(null); //获取(读取):允许读取数据,读取的数据类型为Object Object o = list.get(0); System.out.println(o); }
? extends A:G<? extends A> 可以作为G 和 G的父类,其中B是A的子类
? super A:G<? super A> 可以作为G 和 G的父类,其中B是A的父类