无界通配符
“?”表示类型通配符,用于代替具体的类型。它只能在“<>”中使用。可以解决当具体类 型不确定的问题
public void showFlag(Generic generic){
}
public class Generic<T> { //仅限制为定义时给定的类型,不存在继承一说
private T flag;
public void setFlag(T flag){
this.flag=flag;
}
public T getFlag(){
return this.flag;
}
}
public class ShowMsg {
public void showFlag(Generic<?> generic){
System.out.println(generic.getFlag());
}
}
public class Test {
public static void main(String[] args) {
ShowMsg showMsg=new ShowMsg();
Generic<Integer> generic=new Generic<>();
generic.setFlag(20);
showMsg.showFlag(generic);
Generic<Number> generic1=new Generic<>();
generic1.setFlag(30);
showMsg.showFlag(generic1);
Generic<String> generic2=new Generic<>();
generic2.setFlag("耿");
showMsg.showFlag(generic2);
}
}
通配符上限界定(可适用于泛型)
上限限定表示通配符的类型是 T 类以及 T 类的子类或者 T 接口以及 T 接口的子接口。 该方式同样适用于与泛型的上限限定。
public void showFlag(Generic <? extends Number> generic){
}
public class Generic<T> {
private T flag;
public void setFlag(T flag){
this.flag=flag;
}
public T getFlag(){
return this.flag;
}
}
public class ShowMsg {
public void showFlag(Generic<? extends Number> generic){
System.out.println(generic.getFlag());
}
}
public class Test {
public static void main(String[] args) {
ShowMsg showMsg=new ShowMsg();
Generic<Integer> generic=new Generic<>();
generic.setFlag(20);
showMsg.showFlag(generic);
Generic<Number> generic1=new Generic<>();
generic1.setFlag(50);
showMsg.showFlag(generic1);
// Generic<String> generic2=new Generic<>();
// generic2.setFlag("geng");
// showMsg.showFlag(generic2); //限定了范围,这个无法通过编译
}
}
通配符的下限界定
下限限定表示通配符的类型是 T 类以及 T 类的父类或者 T 接口以
public void showFlag(Generic<? super Integer> generic){
}
逻辑同上线界定,若把上面的代码中的extends 换成 super 将会报错,原因是integer是number的子类
总结
泛型主要用于编译阶段,编译后生成的字节码 class 文件不包含泛型中的类型信息。 类
型参数在编译后会被替换成 Object,运行时虚拟机并不知道泛型。因此,使用泛型时,如下
几种情况是错误的:
- 基本类型不能用于泛型。
Test t; 这样写法是错误,我们可以使用对应的包装类;Test t ; - 不能通过类型参数创建对象。
T elm = new T(); 运行时类型参数 T 会被替换成 Object,无法创建 T 类型的对象,容
易引起误解,所以在 Java 中不支持这种写法