泛型原理:
编译字节码后,泛型被擦除替换为限定类型,如是无限定类型参数则为Object。T 类型变量,T ==》Object T extends Number ==> Number
泛型方法类型推断:
1:可以指定泛型类型,也可不指定
2:不指定,泛型类型为方法几个参数类型共同父类的最小级
public class Test {
public static void main(String[] args) {
/**不指定泛型的时候*/
int i=Test.add(1, 2); //这两个参数都是Integer,所以T替换为Integer类型
Number f=Test.add(1, 1.2);//这两个参数一个是Integer,另一个是Float,所以取同一父类的最小级,为Number
Object o=Test.add(1, "asd");//这两个参数一个是Integer,另一个是String,所以取同一父类的最小级,为Object
/**指定泛型的时候*/
int a=Test.<Integer>add(1, 2);//指定了Integer,所以只能为Integer类型或者其子类
int b=Test.<Integer>add(1, 2.2);//编译错误,指定了Integer,不能为Float
Number c=Test.<Number>add(1, 2.2); //指定为Number,所以可以为Integer和Float
}
//这是一个简单的泛型方法
public static <T> T add(T x,T y){
return y;
}
}
泛型的引用 传递
1:不同泛型不能相互引用
ArrayList<String> arrayList1=new ArrayList<Object>();//编译错误
ArrayList<Object> arrayList1=new ArrayList<String>();//编译错误
ArrayList<Object> arrayList1=new ArrayList<Object>();
arrayList1.add(new Object());
arrayList1.add(new Object());
ArrayList<String> arrayList2=arrayList1;//编译错误
运行时类型查询
arrayList instanceof ArrayList<String> 编译错误
arrayList instanceof ArrayList 或者 arrayList instanceof ArrayList<?>
静态方法和静态类中泛型问题
泛型类中静态方法或者静态变量不可以使用泛型类申明的泛型类型参数
通配符
上界 List<? extends Number>
List<? extends Number> list1=new ArrayList<Integer>();
List<? extends Number> list2=new ArrayList<Float>();
? extends Number 集合list只能get 不能add。反证,如果可以的话那么list就可以添加Integer或者Float 那么在取出的时候就不知道是什么类型
下界
public class Test {
public static void fillNumberList(List<? super Number> list) {
list.add(new Integer(0));
list.add(new Float(1.0));
}
public static void main(String[] args) {
List<? super Number> list=new ArrayList();
list.add(new Integer(1));
list.add(new Float(1.1));
}
}
可以添加Number的任何子类,为什么呢?
List<? super Number>可以代表List<T>,其中T为Number父类,(虽然Number没有父类)。如果说,T为Number的父类,我们想List<T>中加入Number的子类肯定是可以的。
无界通配符
知道了通配符的上界和下界,其实也等同于知道了无界通配符,不加任何修饰即可,单独一个“?”。如List<?>,“?”可以代表任意类型,“任意”也就是未知类型。
List<Object>与List<?>并不等同,List<Object>是List<?>的子类。还有不能往List<?> list里添加任意对象,除了null
常规使用
1、当方法是使用原始的Object类型作为参数时,如下:
public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + "");
System.out.println();
}
可以选择改为如下实现:
public static void printList(List<?> list) {
for (Object elem: list)
System.out.print(elem + "");
System.out.println();
}
这样就可以兼容更多的输出,而不单纯是List<Object>,如下:
List<Integer> li = Arrays.asList(1, 2, 3);
List<String> ls = Arrays.asList("one", "two", "three");
printList(li);
printList(ls);