Fork me on GitHub

java泛型

 泛型类

没有泛型的情况下的容器类

public class Container {
    private String key;
    private String value;
 
    public Container(String k, String v) {
        key = k;
        value = v;
    }
    
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
 
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

有泛型的容器类

public class Container<K, V> {
    private K key;
    private V value;
 
    public Container(K k, V v) {
        key = k;
        value = v;
    }
 
    public K getKey() {
        return key;
    }
    public void setKey(K key) {
        this.key = key;
    }
 
    public V getValue() {
        return value;
    }
    public void setValue(V value) {
        this.value = value;
    }
}

或者是这样的格式

class Util<E>{  
    public E get(E e){  
        return e;  
    }  
}  

泛型方法

一个基本的原则是:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛化,那么应该有限采用泛型方法。

定义泛型方法,格式:修饰符 <类型参数列表> 返回类型 方法名(形参列表) { 方法体 }

    public static <T> T out(T t) {  //打印参数T的实例化t
        System.out.println(t);
return t; }
public static <T> void out(T... args) { //打印多个参数T,args必须是同一种类型 for (T t : args) { System.out.println(t); } }

多个泛型的

public static <T, S> int func(List<T> list, Map<Integer, S> map) {

}

泛型接口

public interface List<E> extends Collection<E> {
    boolean add(E e);
    E get(int index);
}

泛型通配符

?代表所有类型

不使用泛型

    public static void iterator(Collection coll){
    }

    public static void main(String[] args) {
       List<String> list= new ArrayList<String>();
       Set<Integer> set = new HashSet<Integer>();
        iterator(list);
        iterator(set);
    }

因为Collection是List和Set的接口。根据里氏替换原则可以直接替换,所以不报错。

使用泛型

    public static void iterator(Collection<?> coll){
    }

    public static void main(String[] args) {
       List<String> list= new ArrayList<String>();
       Set<Integer> set = new HashSet<Integer>();
        iterator(list);
        iterator(set);
    }

如果用iterator(Collection<String> coll)那么Set<Integer>就会报错,如果用iterator(Collection<Integer> coll)那么List<String>就会报错。

为了满足List<E>和Set<E>,他们的接口Collection只能用Collection<?>

 ? extends 父类/接口

    public static void main(String[] args) {
      //创建3个集合对象
      ArrayList<ChuShi> cs = new ArrayList<ChuShi>();
      ArrayList<FuWuYuan> fwy = new ArrayList<FuWuYuan>();
      ArrayList<JingLi> jl = new ArrayList<JingLi>();
      
      //每个集合存储自己的元素
      cs.add(new ChuShi("张三", "后厨001"));
      cs.add(new ChuShi("李四", "后厨002"));
      
      fwy.add(new FuWuYuan("翠花", "服务部001"));
      fwy.add(new FuWuYuan("酸菜", "服务部002"));
      
      jl.add(new JingLi("小名", "董事会001", 123456789.32));
      jl.add(new JingLi("小强", "董事会002", 123456789.33));
      
      iterator(jl);
      iterator(fwy);
      iterator(cs);
    
    }

    /*
     * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 work
     * ? 通配符,迭代器it.next()方法取出来的是Object类型,怎么调用work方法
     * 强制转换:  it.next()=Object o ==> Employee
     * 方法参数: 控制,可以传递Employee对象,也可以传递Employee的子类的对象
     * 泛型的限定  本案例,父类固定Employee,但是子类可以无限?
     *   ? extends Employee 限制的是父类, 上限限定, 可以传递Employee,传递他的子类对象
     *   ? super   Employee 限制的是子类, 下限限定, 可以传递Employee,传递他的父类对象
     */
    public static void iterator(ArrayList<? extends Employee> array){  //ArrayList<?>也可以,不过在下面遍历时会转为Employee,如果是非Employee的子类类型就会报错
      
       Iterator<? extends Employee> it = array.iterator();
       while(it.hasNext()){
         //获取出的next() 数据类型,是什么Employee
         Employee e = it.next();
         e.work();
       }
    }

 

posted @ 2018-08-24 15:00  秋夜雨巷  阅读(283)  评论(0编辑  收藏  举报