泛型的分类
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 一样 } }