通配符
497字约2分钟
2024-08-08
无界通配符
Java的泛型允许使用无限定通配符(Unbounded Wildcard Type
),即只定义一个 ?
我们知道 Ingeter
是 Number
的一个子类,但是 Generic<Number>
作为形参的方法中,Generic<Ingeter>
的实例却不能传入
public static void main(String[] args) {
// 编译报错
showName(new Animal<Integer>());
}
public static void showName(Animal<Number> obj) {
System.out.println(obj.getName());
}
public class Animal<T> {
private T name;
private T type;
public T getName() {
return name;
}
public T getType() {
return type;
}
}
我们把 showName()
方法修改一下就可以传入 new Animal<Integer>()
了
public static void showName(Animal<?> obj) {
System.out.println(obj.getName());
}
因为 <?>
通配符既没有 extends
,也没有 super
,因此
不允许调用
set(T)
方法并传入引用(null
除外)不允许调用
T get()
方法并获取T
引用(只能获取Object
引用)
extends 通配符
使用 <? extends Number>
的泛型定义称之为上界通配符(Upper Bounds Wildcards
),即把泛型类型 T
的上界限定在 Number
了
public static void main(String[] args) {
showName(new Animal<Integer>());
showName(new Animal<Double>());
}
public static void showName(Animal<? extends Number> obj) {
Number name = obj.getName();
System.out.println(obj.getName());
// 编译报错,可以设置为null
obj.setName(name);
}
使用类似 <? extends Number>
通配符作为方法参数时表示:
方法内部可以调用获取
Number
引用的方法,例如:Number name = obj.getName();
方法内部无法调用传入
Number
引用的方法(null
除外),例如:obj.setName(Number n);
super 通配符
使用 <? super Integer>
的泛型定义称之为下界通配符(down Bounds Wildcards
),即把泛型类型 T
的上界限定在 Integer
了
public static void main(String[] args) {
showName(new Animal<Integer>());
showName(new Animal<Number>());
}
public static void showName(Animal<? super Integer> obj) {
obj.setName(1);
// 获取为 Integer 编译报错;获取为父类类型可以
Integer name = obj.getName();
System.out.println(obj.getName());
}
使用类似 <? super Integer>
通配符作为方法参数时表示:
方法内部可以调用传入
Integer
引用的方法,例如:obj.setName(Integer n);
方法内部无法调用获取
Integer
引用的方法(Number
、Object
除外),例如:Integer n = obj.getName();