关于泛型的使用

来源:互联网 发布:java代码块执行顺序 编辑:程序博客网 时间:2024/06/06 13:58
一,为什么要使用泛型
    泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型
或者是某个方法的返回值及参数类型。这样在类声明或实例化时只要指定好需要的具体的类型即可。Java泛型可以保证如果
程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮。如图所示:


二,示例
代码示例如下:
package com.atguigu.java;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.junit.Test;/* * 泛型的使用 * 1.在集合中使用泛型(掌握) * 2.自定义泛型类、泛型接口、泛型方法(理解 --->使用) * 3.泛型与继承的关系 * 4.通配符 *  */public class TestGeneric {/** 通配符的使用*/    @Test    public void test7(){        List<String> list = new ArrayList<String>();        list.add("AA");        list.add("BB");        List<?> list1 = list;//可以读取声明为通配符的集合类的对象        Iterator<?> iterator = list1.iterator();        while(iterator.hasNext()){            System.out.println(iterator.next());        }//不允许向声明为通配符的集合类中写入对象。唯一例外的是null        // list1.add("CC");        // list1.add(123);        list1.add(null);    }/** 通配符 ?* List<A>、List<B>、。。。。都是List<?>的子类* * ? extends A :可以存放A及其子类* ? super A:可以存放A及其父类*/    @Test    public void test6(){        List<?> list = null;        List<Object> list1 = new ArrayList<Object>();        List<String> list2 = new ArrayList<String>();        list = list1;        list = list2;        show(list1);        // show(list2);        show1(list1);        show1(list2);        List<? extends Number> list3 = null;  //表示使用任何Number类或其子类都可以,只是只能对其对象进行读操作,而不能进行写操作;        List<Integer> list4 = null;           //List<? extends Number>同List<T extends Number>两者是等效的;        list3 = list4;        //list3 = list1;        List<? super Number> list5 = null;        list5 = list1;    }    public void show(List<Object> list){    }    public void show1(List<?> list){    }/** 泛型与继承的关系:* 若类A是类B的子类,那么List<A>就不是List<B>的子接口*/    @Test    public void test5(){        Object obj = null;        String str = "AA";        obj = str;        Object[] obj1 = null;        String[] str1 = new String[]{"AA","BB","CC"};        obj1 = str1;        List<Object> list = null;        List<String> list1 = new ArrayList<String>();        //list = list1;        //假设list = list1满足        //list.add(123);        //String str = list1.get(0);//出现问题,所以假设不满足    }//自定义泛型类的使用    @Test    public void test4(){        //1.当实例化泛型类的对象时,指明泛型的类型。        //指明以后,对应的类中所有使用泛型的位置,都变为实例化中指定的泛型的类型        //2.如果我们自定义了泛型类,但是在实例化时没有使用,那么默认类型是Object类的        Order<Boolean> order = new Order<Boolean>();        // order.getT();        order.setT(true);        System.out.println(order.getT());        order.add();        List<Boolean> list = order.list;        System.out.println(list);        SubOrder o = new SubOrder();        List<Integer> list1 = o.list;        System.out.println(list1);        //当通过对象调泛型方法时,指明泛型方法的类型。        Integer i = order.getE(34);        Double d = order.getE(2.3);        Integer[] in = new Integer[]{1,2,3};        List<Integer> list2 = new ArrayList<>();        List<Integer> list3 = order.fromArrayToList(in, list2);        System.out.println(list3);    }    @Test    public void test3(){        Map<String,Integer> map = new HashMap<>();  //在JDK7.0之后,可以省略后者如HashMap<>中的<>中的类型,但是<>需要保留;        map.put("AA", 78);        map.put("BB", 87);        map.put("DD", 98);                Set<Map.Entry<String,Integer>> set = map.entrySet();        for(Map.Entry<String,Integer> o : set){        System.out.println(o.getKey() + "--->" + o.getValue());        }    }//2.在集合中使用泛型    @Test    public void test2(){        List<Integer> list = new ArrayList<Integer>();//使用泛型之后,它就只能往List中添加某种指定类型的对象了;        list.add(78);                                 //而不能添加这个类的父类或子类亦或其他类的对象;        list.add(87);        // list.add("AA");        // for(int i = 0;i < list.size();i++){        // int score = list.get(i);        // System.out.println(score);        // }        Iterator<Integer> it = list.iterator();        while(it.hasNext()){            System.out.println(it.next());        }    }//1.在集合中没有使用泛型的情况下    @Test    public void test1(){        List list = new ArrayList();        list.add(89);        list.add(87);        list.add(67);        //1.没有使用泛型,任何Object及其子类的对象都可以添加进来        list.add(new String("AA"));        for(int i = 0;i < list.size();i++){            //2.强转为int型时,可能报ClassCastException的异常            int score = (Integer)list.get(i);            System.out.println(score);        }    }}



Order类的代码示例如下:
package com.atguigu.java;import java.util.ArrayList;import java.util.List;//自定义泛型类public class Order<T> {    private String orderName;    private int orderId;    private T t;    List<T> list = new ArrayList<>();    public void add(){        list.add(t);    }    public  T getT(){        return t;    }    public void setT(T t){        this.t = t;    }//不可以在static方法中使用泛型的声明    //public static void show(){        // System.out.println(t);    //}    public void info(){        //不可以在try-catch中使用类的泛型的声明        // try{        //         // }catch(T e){        //         // }    } //声明泛型方法    public static <E> E getE(E e){        return e;    }//实现数组到集合的复制    public <E> List<E> fromArrayToList(E[] e,List<E> list){        for(E e1 : e){            list.add(e1);        }        return list;    }    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;    }@Override    public String toString() {        return "Order [orderName=" + orderName + ", orderId=" + orderId        + ", t=" + t + "]";    }}//继承泛型类或泛型接口时,可以指明泛型的类型,如下所示;当然若你仍然没有指定泛型的类型时,//此时,继承的子类需要写成:class SubOrder<T> extends Order<T>{}class SubOrder extends Order<Integer>{}


注:可参考源码关于泛型类及泛型方法的自定义,如:Collection类

注:泛型类的使用注意点
1.对象实例化时不指定泛型,默认为:Object。
2.泛型不同的引用不能相互赋值。
3.加入集合中的对象类型必须与指定的泛型类型一致。
4.静态方法中不能使用类的泛型。(因为泛型只有在创建对象时,才能确定其类型,而static是在类创建时,就存在,所以两者不能共存)
5.不能在catch中使用泛型 (具体见Order类中的public void info()方法)
6.从泛型类派生子类,泛型类型需具体化

0 0