1.类型参数:更好可读性,安全性
a)<T,U extends Comparable&Serializable> 确保实现某接口 可以是类,接口(extends接近子类概念)
b)类放第一,只能一个,接口可多个
2.通配符类型(可限制只能单向调用)
3.
public class Pair<T> {
private T a;
public Pair(T a) {
this.a = a;
}
public T getA() {
return a;
}
public void setA(T a) {
this.a = a;
}
public static void main(String[] args) {
Pair<String> a = new Pair<String>("testttt");
System.out.println(a.getA());
}
}
4.T U,S表示任意类型,<K,V>表身key,value,<E>集合元素
5.泛型方法
public static <T> T test(T[] in){
return in[in.length/2];
}
//调用 ClassA.test(..) ClassA.<String>Test(...);
5.虚拟机没有泛型,都为普通类
a)定义泛型,提供原始类型(raw type)
b)擦除类型变量,替换限定类型(无用Object,有的话用第一个类型)
6.翻译泛型表达式
a)原始方法调用
b)强制转换,安全转换
c)引入桥方法,多态实现
7.参数名相同,返回值不同是不允许的,虚拟机却可识别
j2se5.0 方法覆盖可返回更严格的返回类型
8.限制
a)不能用基本类型做类型参数(擦除至少要含有Object)
b)运行时类型检测只适用于原始类型
if(a instanceOf Pair<T>) //or Pair<String>
Pair<String> a=Pair<T>b;
a.getClass-->Pair.class
c)不能抛出,不能捕获泛型实例(Throwable),不能在catch(T e)
public class Problem<T> extends Throwable //illegal
public class Problem<T extends Throwable> //legal 异常类型
d)参数化类型数组非法 Pair<String>[] .. 数组能记忆类型(component type)
推荐ArrayList<Pair<String>>
e)不能实例化类型变量 a=new T();
T.class 非法 要是Class<T> c 声明
f)数组做私有域
public class ArrayList<E>{
private Object[] elements;//E[]
public E get(int n){
return (E)elements[n];//cast
}
public void set(int n,E e){
elements[n]=e;//elements[n]=(E[])new Object[10];
}
}
//object->string会出问题
T[] mm=(T[])Array.newInstance(a.getClass.getComponentType,2);//实例
g)禁止带类型变量静态域/方法 (类型擦除)
h)注意擦除后冲突 boolean equals(T value)
若继承2个接口的祖先不能同一接口,可能桥接冲突
g)类型变量无继承关系 Pair<T> Pair<S> 可包含于Pair
数组可以继承关系,可赋值(多态)
h)可继承
9.通配符的类型参数 <? extends Employee>