Java高级之---泛型的使用

一、泛型的概念

1.什么是泛型,看表面的意思,泛型就是指广泛的、普通的类型
2. 所谓泛型,就允许在定义类、接口时通过圆滚滚标识表示类中的某个属性的类型或者某个方法的返回值及参数类型。

这个参数类型将在使用的时候就确定了。

使用泛型有哪些好处

(1)首先就像上面那个例子一样,使用泛型能够限定集合中,如List, Set中元素的类型,保证一个集合中只有一个类型。
(2)程序也能更加健壮(只要在编译时期没有出现警告,那么运行时期就不会出现ClassCastException异常)

二、泛型的使用

1.jdk5.0新增的特性

2.集合中使用泛型

①在集合接口或集合类中在jdk5.0时都修改为带泛型的结构。
②在实例化集合类时,可以指明泛型的类型
③指明完后,在集合类或者接口中凡是定义类和接口时,内部结构都使用到类的泛型的位置,都指定为实例化时的泛型类型
比如:add(E e)----->实例化后add(Integer e)
④泛型的类型必须是类,不能是基本数据类型需要用到基本数据类型的时候,使用它的包装类
⑤如果实例化时,没有指定泛型类型,默认为Object类型

3、自定义泛型结构:泛型类、泛型接口、泛型方法

4.自定义泛型的注意

在集合中使用泛型之前的情况:
 ArrayList list  = new ArrayList();

        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        //其他类型出现
        //问题一、类型不安全
//        list.add("Tom");

        for (Object score : list){
            //问题2:出现异常,ClassCastException
            int stuScore = (int)score;
            System.out.println(stuScore);
        }
在集合中使用泛型的情况:

泛型是一个类型,但是不能是基本数据类型,所有需要使用包装类

 ArrayList list = new ArrayList();

        list.add(60);
        list.add(70);
        list.add(80);
        list.add(90);
        list.add(100);
        //编译时,就会进行类型检查,保证数据的安全性
//        list.add("Tom");
        //方式一
        for (Integer score:list){
            //避免了强转出现的异常
            int stuScore = score;
        }
        //方式二
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
//            System.out.println(iterator.next());
            int next = iterator.next();
            System.out.println(next);
        }
在集合中使用泛型的情况:以HashMap为例
 Map map = new HashMap();

        map.put("Tom",123);
        map.put("Tom1",123);
        map.put("Tom2",456);
        map.put("Tom3",789);
        map.put("Tom4",159);
        //编译错误
        //        map.put(741,"Tmo5")

        //泛型的嵌套Entry为Map的内部接口
        Set> entries = map.entrySet();

        Iterator> iterator = entries.iterator();

        while (iterator.hasNext()){
            Map.Entry next = iterator.next();
            System.out.println(next);//Tom=123键值
            String key = next.getKey();
            Integer value = next.getValue();
            System.out.println("key = " + key + ",value = " + value);//key = Tom,value = 123 键和值
        }
三、自定义泛型类

注意事项:
Java高级之---泛型的使用_第1张图片
Java高级之---泛型的使用_第2张图片
自定义泛型类

public class Order {
    String orderName;
    int orderId;
    //类的内部结构,就可以使用类的泛型

    T orderT;
    public Order(){
        //编译不通过
//        T[] arr =   new T[20]
    }

    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;
    }

    @Override
    public String toString() {
        return "Order{" +
                "orderName='" + orderName + '\'' +
                ", orderId=" + orderId +
                ", orderT=" + orderT +
                '}';
    }
    //静态方法中不能使用类的泛型
//    public static void show(T orderT){
//        System.out.println(orderT);
//    }
    public void show(){
        //编译不通过,泛型不能时异常类型
//        try {
//
//        }catch (T t){
//
//        }
    }
    //泛型方法,在方法中出现了泛型的结构,泛型的参数与类的泛型参数没有任何关系。
//    public static   List copy(E[] arr){}
    //泛型方法,在不在泛型类中都没有关系
    //泛型方法可以是静态的:原因:泛型参数是在调用时确定的,并不是在实例化时确定的。
    public static  List copy(E[] arr){
        ArrayList list = new ArrayList<>();
        for (E e:arr){
            list.add(e);
        }
        return list;
    }
}


不是泛型类只是继承了泛型
public class SubOrder extends Order {//不是泛型类
    //泛型方法,在不在泛型类中都没有关系
    public static  List copy(E[] arr){
        ArrayList list = new ArrayList<>();
        for (E e:arr){
            list.add(e);
        }
        return list;
    }
}

这种也是泛型类

public class SubOrder1 extends Order {//泛型类
}

1.如果定义了泛型类,实例化时没有指定类的泛型,则认为泛型的类型为Object类型
//        Order order = new Order();
//        order.setOrderT(123);
//        order.setOrderT("ABC");

        //要求,如果定义了为带泛型的类,建议在实例化时要指明泛型的类型
//        Order order = new Order();
//        order.setOrderT(123);
        //带上泛型后,指明了类型
//        order.setOrderT("ABC");

        Order order = new Order<>("orderAA", 1001, "order:AA");
        order.setOrderT("AA:hello");
//        order.setOrderT(123);
2.由于子类在继承带泛型的父类时,指明了泛型的类型,则在子类实例化时,不在需要指明泛型的类型
	    SubOrder subOrder = new SubOrder();
        subOrder.setOrderId(123);

        SubOrder1 subOrder1 = new SubOrder1();
//        subOrder1.setOrderT("AA");
        subOrder1.setOrderT(123);
3.泛型不同的引用不能互相复制
    ArrayList  list1 = null;
    ArrayList  list2 = null;
    //编译报错,类型不同

// list1 = list2;

4.测试泛型方法
 Order order = new Order<>();
        Integer[] arr = new Integer[]{1,2,3,4};
        //泛型方法在调用时,指明泛型参数的类型
        List copy = order.copy(arr);//自定义泛型类中有该方法
        System.out.println(copy);//[1, 2, 3, 4]
四、泛型在继承方面的体现

虽然类A是类B的父类,但是G< A > 和 G < B > 二者不是父类,为并列关系
类A是类B的父类 A< G > 是 B< G >的父类

 @Test
   public void test(){
       Object obj = null;
       String str = null;
       obj = str;

       List list1 = null;
       List list2 = null;
       //编译错误,类型不具备子父的关系
//        list1 = list2

       show(list1);
       show1(list2);

   }
   public void show(List list){
   }
   public void show1(List list){
   }
 
  

类型相同,编译才不会报错

    List list = null;
    ArrayList list1 = null;
   
       list = list1;
通配符的使用 通配符:?

类A是类B的父类,但是G< A > 和 G< B >为并列关系,二 者 共 同 的 父 类 为 G < ?>

  List list1 = null;
        List list2 = null;

        List list = null;

        list = list1;
        list = list2;
        //编译通过
//        print(list1);
//        print(list2);

        //使用通配符后,数据的读写要求
        List list3 = new ArrayList<>();
        list3.add("AA");
        list3.add("BB");
        list3.add("CC");

        list =list3;
        //添加(写入)报错,对于List就不能向其内部添加数据,除了null以外
//        list.add("DD");
          list.add(null);

        //获取(读取):允许读取数据,读取的类型为Object
        Object o = list.get(0);
        System.out.println(o);
        
 public void print(List list){
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }
    }
 
  
有限制条件的通配符使用

Student类继承自Person
? extends Person
? super Student

? extends A :G< ? extends A > 可以看作G< A > 和 G < B >的父类,其中B是A的子类
? super A:G< ? super A> 可以作为G< A > 和 G< B >的父类,其中B是A的子类

练习、如果遍历Map的key集,value集,key-value集,使用上泛型
  Map map = new HashMap();
        map.put("Tom",123);
        //获取key集
        Set strings = map.keySet();
        for (String key:strings){
            System.out.println(key);
        }
        //遍历value集
        Collection values = map.values();
        Iterator iterator = values.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //遍历key-value集
        Set> entries = map.entrySet();
        Iterator> iterator1 = entries.iterator();
        while (iterator1.hasNext()){
            Map.Entry next = iterator1.next();
            String key = next.getKey();
            Integer value = next.getValue();
            System.out.println(key +" +++++++++ " + value);
        }


        //提供一个方法用于遍历获取HashMap中的所有value,并存放到list集合中返回,使用泛型
        public List getValueList(HashMap map){
        ArrayList valueList = new ArrayList<>();
        Collection values =map.values();
        for (String value :values){
            valueList.add(value);
        }
        return valueList;
    }
五、泛型在开发中的使用场景

DAO:data(base) access object 数据访问对象

public class DAO {
    //添加
    public void add(T t){

    }
    //删除
    public boolean remove(int index){
        return false;
    }
    //修改
    public void update(int index,T t){

    }
    //查询
    public T getIndex(int index){
        return null;
    }
    //查询多条记录
    public List getForList(int index){
        return null;
    }
}

你可能感兴趣的:(java)