Java 泛型 (一)

泛型的分类

1. 泛型类与接口

2. 泛型方法

package generic;

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

/**
 * 泛型类及泛型方法
 */
public class GenericClass<E> {
    private E data;
    public E getData() {
        return data;
    }
    
    // 泛型方法
    // 这个方法可以通过Class对象生成任意对象的List
    public <T> List<T> getT(Class<T> cls, int size) {
        List<T> list = new ArrayList<T>();
        try {
            for (int i = 0; i < size; i++) {
                // 其局限型就在于CLASS对应的类必须包含无参构造方法
                list.add(cls.newInstance());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
}


package generic;

public interface GenericInter<E> {
    E get();
}


package generic;

public class GenericInterImpl implements GenericInter<String>{
    @Override
    public String get() {
        return null;
    }
}

 

泛型的边界

package generic;

public class Holder<E> {
    private E data;
    public void set(E e) {
        this.data = e;
    }
    public E get() {
        return data;
    }
}


package generic;

public class BoundTest {
    // 原生形参方法
    public void rawArgs(Holder holder, Object o) {
        holder.set(o);
        // 由于形参holder没有指定其泛型数据类型,编译会产生警告
        Object obj = holder.get();
        Integer i = (Integer) holder.get();    
        // 可能会有异常,因为无法知道holder里放的是什么类型的数据
        // 所以编译的时候会产生警告
        
    }
    
    // 无界形参方法
    public void unboundedArgs(Holder<?> holder, Object o) {
        // holder.set(0);
        // 这一句无法通过编译,因为 Holder<?> 的意思是 holder 需要
        // 指定确切的泛化数据类型,个人认为无界通配符 ? 的用处就是通知
        // 编译器这个 holder 需要指定确切的数据类型,而不能随意用其他
        // 类型去使用这个 holder
        
        Object obj = holder.get();
        Integer i = (Integer) holder.get();
        // 实际上唯一 get() 方法的返回值唯一能匹配保证不会出错的就只有
        // Object 类而已
    }
    
    // 确定下界的泛型
    public <T> void wildSubType(Holder<? extends T> holder, T arg) {
        // holder.set(arg);
        // 这一句会编译出错,想象当我们调用这个方法的时候,我们会如何传参,如下
        // Holder<ArrayList> holder = new Holder<ArrayList>();
        // Collection arg = new HashMap();
        // wildSubType(holder, arg);
        // 意义想象上面的holder和arg传入后,调用holder的set()方法会出现什么
        // 结果,这就是编译器在确定泛型下界的时候为什么不允许用 T 去替代 ? extends T
        // 的原因,因为 T 有可能是Map,而我们的 ? 却是一个List
        
        T t = holder.get();
        // 这一句可以执行,因为 ? extends T ,则 ? 肯定是一个 T 类型
    }
    
    // 确定上界的泛型
    public <T> void wildSuperType(Holder<? super T> holder, T arg) {
        holder.set(arg);
        // 这句可以执行,因为 ? super T, 则 T 必是 ? 的衍生类
        
        // T t = holder.get();
        // 这句无法编译通过,因为 ? super T 未必就是 T, 就 ? 是一个Collection
        // 而 T 却是一个 ArrayList 一样
    }
}

 

 

你可能感兴趣的:(java 泛型)