Java泛型及通配符

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中不能使用泛型
  • 如泛型类是接口或者抽象类,则不能创建泛型类的对象(接口和抽象类不可实例化)
  • 从泛型类派生出子类,泛型类型需具体化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值