通配符
? 声明在变量或者形参上面
List<?> list = new ArrayList<Integer>();
void test(List<?> list);
上下限
上限
void test(List<? extends fruit> list);
List<apple> list1 = new ArrayList<>();
test(list1);
//test方法里放的上限是水果类,只能是水果或者是水果的子类泛型
//不可以用?,List<?> list2; test(list2)报错
List<? extends apple> list3;
test(list3);//可以执行,泛型是水果子类
//只能add(null)
//一般用于读取数据,添加数据几乎不用这个
void test(List<? extends apple> list) {
//如果传入的参数是List<? extends apple> list =new ArrayList<buleApple>();
//报错
list.add(new Fruit());
//报错
list.add(new RedApple());
}
下限,放入对象泛型的下限是自己
//super是指父类或者自己
test(List<? super Apple> list);//放入的是苹果的父类或者自身泛型
List<Fruit> list1;
test(list1);
List<Apple> list2;
test(list2);
List<Object> list3;
test(list3);
//不能添加父类对象
test(List<? super redapple> list) {
//如果传入的是<apple>
//红苹果的子类拥有父类一切
list.add(new chinaRedApple());
list.add(new Apple());
//报错,List<apple> list;
list.add(new Fruit());
}
泛型方法
/**
*非泛型类中也可以定义泛型方法的
*在 返回类型的前面加上 <字母>
*/
public class MyShow {
public static <T> void test(T t) {
System.out.println(t);
}
//继承List类,这样T就是List的子类
public static <T extends List> void test(T t) {
t.add("jack");
t.remove("jack");
System.out.println(t);
}
}
泛型类
/**
* 1.自定义泛型类,最好是单个大写字母,尽可能的见名知意
*
* 2.
* T type
* k v key value
* E element
*
* 3.泛型不能用在静态属性上,使用的时候不能是基本类型
* new MyShow<int>(); //这样是错误的
*/
public class MyShow<T> {
private T javabean;
}
擦除
public class Father<T1,T2> {
//保留
//c1.全部保留
class C1 extends Father<T1,T2>{}
//c2.部分保留
//class C2 extends Father<Integer,T3>{}//编译错误
//class C2 extends Father<Integer,T2>{}
class C2 extends Father<Integer,T1>{}
//不保留
//c3.具体类型
class C3 extends Father<Integer,String>{}
//c4.没有类型(擦除)类似于object,不等于object
class C4 extends Father{}
}
泛型接口
int school_num = 101;
接口中定义的常量是默认携带:public static final的
在接口中定义的泛型,不能作用在常量中。