Java泛型的个人小结
1)泛型参数只能是类类型
例如:List<int> // 报错
List<Integer> // 正确
2)泛型的类型参数可以有多个!
例如:List<Integer,String,Boolean> list = new ArrayList<Integer,String,Boolean>();
3)泛型的参数类型可以使用extends,习惯称“有界类型”,
例如:List<student extends person>,person为list的上界
4)泛型可以使用通配符类型!“?” 相当于“Object”类型,(注意不可逆)
例如:List<?> //定义成这样可以添加Object类型到List里面去
List<Object>; //定义成这样不可以添加String类型到List里面去
List<? extends Object>; // 这样就可以互等了!这样还可以设定泛型的上限
5)带泛型的类,构造方法写法不变,其后不可以加泛型!
例如:class Student<T>{
public Student<T>(){} // 构造方法这样写就错了
}
6)List<String> 不是 List<Object> 的子类!,不可以把前者看成后者的子类,所以不 可以把前者的实例赋给后者
例如: List<String> Slist = new ArrayList<String>();
Slist.add(new String("abc"));
List<Object> Olist = new ArrayList<Object>();
Olist.add("abc");
Olist = Slist; // 报错!
7)带不同泛型参数的实例可以共享类的静态方法和静态变量,所以静态方法和静态变量
申明的时候不可以使用类型行参
例如:class Cup<T>{
static T info; // 报错!
public static setInfo(T info){}; // 报错!
}
8)带不同泛型参数的类是共享一个字节码文件的!反编译过后泛型参数就被擦除了
例如:List<String> Slist = new ArrayList();
Slist.add(new String("aaa"));
List<Integer> Ilist = new ArrayList();
Ilist.add(new Integer(100));
System.out.println(Slist.getClass()==Ilist.getClass());
结果为true;
9)当使用定义了泛型参数的接口 和 父类的时候!就不能在带参数了
例如:class Sub extends Father<String> {} // 错误
10)
class T<E>{}
public class typeTest extends T<E>{}//报错 class T<E>{}
public class typeTest extends T<Integer>{} // 正确 可使用String等基本封装类型 class T<E>{}
class Student{}
public class typeTest extends T<Student>{} // 这样也正确
11) 泛型方法 ,泛型方法的参数的作用域仅在本方法,要和方法带泛型区分开!
Static <T> void test(List<String> S_list){} // 泛型参数要放在返回类型前
12)带有泛型的代码转换成没有泛型的代码由javac完成,虚拟机不处理这些事情!
这种技术叫做 “擦除”;
例如:class Food<T extends Number>{
T size;
public Food(T size){} //注意构造方法不可以带泛型参数!
public void setSize(){ this.size = size; }
public T getSize(){ return this.size;}
}
public class test{
public static void main(String arg[]){
Food<Integer> a = new Food<Integer>(6);
Ingeger as = a.getSize(); // 返回的是Integer的类型
Food b = a; //把a对象赋给Food变量;泛型参数类型会丢失 即擦除;
Number size1 = b.getSize(); // b只知道size的类型是Number
// Integer in = b.getSize(); 这样是编译错误的!
}
}
|