26、泛型

泛型的概念

在编写集合相关代码时在eclipse里面总有一些黄色警告,在不使用注解的情况下,使用泛型之后,就不会有这些黄色警告了。
通过API可以看到Collection,List,ArrayList,这几个类里面都有,这个就是泛型,里面的E可以是任何引用数据类型,使用泛型指明了数据类型之后,这个集合里面只能存储这种数据类型的对象。

不使用泛型时,要进行多次类型强制转换

package com.monkey1024.generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.monkey1024.bean.Person;

/**
 * 不使用泛型的缺点
 * 
 */
public class GenericTest01 {

    public static void main(String[] args) {
        List list = new ArrayList();
        //如果不使用泛型可以像list中存放不同的数据类型
        list.add("monkey");
        list.add(1024);
        list.add(new Person("刘德华", 51));

        Iterator iter = list.iterator();
        while(iter.hasNext()){
            //只能做大量的类型判断
            Object obj = iter.next();
            if(obj instanceof String){
                String s = (String)obj;
            }
            if(obj instanceof Integer){
                Integer i = (Integer)obj;
            }
            if(obj instanceof Person){
                Person p = (Person)obj;
            }

        }
    }

}

使用泛型之后:

package com.monkey1024.generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.monkey1024.bean.Person;

/**
 * 使用泛型
 * 
 */
public class GenericTest02 {

    public static void main(String[] args) {
        //前后数据类型保持一致
        List<Person> list = new ArrayList<Person>();
        //jdk7加入的菱形泛型
        List<Person> list7 = new ArrayList<>();
        //下面代码编译报错
        // list.add("monkey");
        // list.add(1024);
        list.add(new Person("刘德华", 51));

        Iterator<Person> iter = list.iterator();
        while(iter.hasNext()){
            Person p = (Person)iter.next();
        }
    }

}

泛型的优点

  • 可以统一集合中的数据类型,提高安全性
  • 可以减少强制类型转换

自定义泛型

通过JDK的源码可以看到,泛型一般写的都是或者,里面的T和E就是表示使用者指定的类型。可以自己定义一个使用泛型的类

package com.monkey1024.generic;
/**
 * 自定义泛型
 * 类上面使用泛型
 * @param <T>
 */
public class Value<T> {

    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    //方法的泛型最好与类一致,如果不一致需要在方法上面声明泛型
    public<M> void show(M m){
        System.out.println(m);
    }

  
}

泛型通配符

在实际工作当中,有可能通过调用某个方法来接受一个返回值List的数据,这样就不太好确定返回值中的数据类型,这样可以使用泛型通配符<?>

List<?> list = new ArrayList<Integer>();//=号右边可能是通过调用某个方法返回的List
使用泛型通配符限定子类或者父类
? extends E
向下限定,E及其子类,可以存储当前类型的子类
? super E
向上限定,E及其父类,可以存储当前类型的父类
定义一个Student类继承Person
package com.monkey1024.bean;

public class Student extends Person {

    public Student() {
        super();
    }
    public Student(String name, int age) {
        super(name, age);
    }
}

在List中方法addAll是限定了子类(? extends E),定义测试类:

package com.monkey1024.generic;

import java.util.ArrayList;
import java.util.List;

/**
 * ? extends E 向下限定,E及其子类,可以存储当前类型的子类 
 * ? super E 向上限定,E及其父类,可以存储当前类型的父类
 *
 */
public class GenericTest03 {

    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("张三", 23));
        personList.add(new Person("李四", 24));
        personList.add(new Person("王五", 25));

        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student("赵六", 26));
        studentList.add(new Student("周七", 27));

        //因为studentList中存放的Student是Person类的子类,所以可以将studentList放入personList中
        personList.addAll(studentList);
        System.out.println(personList);
    }

}
原文地址:https://www.cnblogs.com/zhuifeng-mayi/p/10131902.html