Java泛型及通配符

来源:互联网 发布:mac上有什么好玩的网游 编辑:程序博客网 时间:2024/06/05 22:01

Java泛型

一直在项目中使用泛型,但对它的概念很模糊,查看了些资料,做个总结,供以后参考。
泛型的核心思想(以下结论以集合为例):把一个集合的内容限制为一个特定的数据类型,这就是generics背后的核心思想。

泛型类或接口的申明

import java.util.ArrayList;import java.util.List;/** * ============================================= * 作    者:Junl * 版    本:1.0 * 创建日期:2017/5/17 * 描    述: * 文艺青年:人生若只如初见,何事秋风悲画扇。 * ============================================= */public class Order<T> {    private String name;    private int age;    private T t;    ArrayList<T> list = new ArrayList<>();    public void add() {        list.add(t);    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public T getT() {        return t;    }    public void setT(T t) {        this.t = t;    }    /**     * 泛型方法  泛型方法 类型<E> 跟 泛型类<T> 类型不是同一个类型     * @return     */    public <E> E getE(E e) {        return e;    }    /**     * 泛型方法  将Array ----> List     * @param e     * @param list     * @param <E>     * @return     */    public <E> List<E> getArray2List(E[] e, List<E> list) {        for (E e1 : e) {            list.add(e1);        }        return list;    }    @Override    public String toString() {        return "Order{" +                "name='" + name + '\'' +                ", age=" + age +                ", t=" + t +                ", list=" + list +                '}';    }}/** * 继承泛型类或泛型接口时,可以指明泛型类型 * * DAO:datebase access object:数据库访问对象  即通过java程序访问数据库中的数据,将结果通过对象形式返回。泛型  在实例化的时候需要指明类型 */class SubOrder extends Order<Integer> {}

测试类

import org.junit.Before;import org.junit.Test;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;/** * ============================================= * 作    者:Junl * 版    本:1.0 * 创建日期:2017/5/17 * 描    述:单元测试自动生成类,在该类方法中,写入需要测试的代码,点击类名CalculatorTest 运行 或者直接点击方法名运行,查看控制台输出结果 * 文艺青年:人生若只如初见,何事秋风悲画扇。 * @link :http://www.jianshu.com/p/03118c11c199 * ============================================= */public class CalculatorTest {    @Before    public void setUp() throws Exception {    }    /**     * Map集合的遍历     * @throws Exception     */    @Test    public void substract() throws Exception {        Map<Integer, String> map = new HashMap<>();        map.put(1, "junl");        map.put(2, "xiaoliang");        map.put(3, "liangliang");        Set<Map.Entry<Integer, String>> set = map.entrySet();        for (Map.Entry<Integer, String> temp : set) {            System.out.println(temp.getKey() + "------>" + temp.getValue());        }    }    /**     * foreach 循环     * @throws Exception     */    @Test    public void divide() throws Exception {        List<String> list = new ArrayList<>();        list.add("hello");        list.add("junl");        list.add("!");        for (String temp : list) {            System.out.print(temp);        }    }    /**     * 泛型  在实例化的时候需要指明类型     * 泛型的核心思想:把一个集合的内容限制为一个特定的数据类型,这就是generics背后的核心思想     * 1、静态方法/catch中,不能使用类的泛型     * 2、如泛型类是接口或者抽象类,则不能创建泛型类的对象(接口和抽象类不可实例化)     * 3、从泛型类派生出子类,泛型类型需具体化     *     * @throws Exception     */    @Test    public void multiply() throws Exception {        Order<Integer> order = new Order<>();        //调用成员变量方法        order.setT(123);        ArrayList<Integer> list = order.list;        order.add();        System.out.println(list.toString());        //调用泛型方法<传递参数是什么类型,输出什么类型的结果>        String e = order.getE("泛型方法");        System.out.println(e);        Boolean[] bo = {true, false, true, false};        ArrayList<Boolean> li = new ArrayList<>();        //将数组转换为集合        List array2List = order.getArray2List(bo, li);        System.out.println(array2List);    }    /**     * 通配符 ?     * List<A> 、List<B> ...都是List<?>的子类     *     * ? extends E :表示可以存放E及其子类     * ? super E :表示可以存放E及其父类     *     * @throws Exception     */    @Test    public void test1() throws Exception {        List<?> list = null;        List<Object> list1 = new ArrayList<>();        list1.add(true);        list1.add(123);        list = list1;        show(list);//可以读取读取申明为通配符的集合类的对象        List<String> list2 = new ArrayList<>();        list2.add("Hello World");        list = list2;        show(list);        //通配符   ? extends E :表示可以存放E及其子类        List<? extends Number> list3 = null;        List<Integer> list4 = new ArrayList<>();        list3 = list4;        //通配符 ? super E :表示可以存放E及其父类        List<? super String> list5 = null;        list5 = list2;    }    /**     * 可以读取读取申明为通配符的集合类的对象  但不允许向申明通配符的集合中写入对象 (null除外)     * @param collection     */    public void show(Collection<?> collection) {        Iterator<?> iterator = collection.iterator();//Iterator<E> iterator();        while (iterator.hasNext()) {            System.out.println(iterator.next());        }    }}

使用泛型需注意

  • 静态方法或catch中不能使用泛型
  • 如泛型类是接口或者抽象类,则不能创建泛型类的对象(接口和抽象类不可实例化)
  • 从泛型类派生出子类,泛型类型需具体化