一 、匹配任意类型的通配符
观察以下程序:
class Info<T>{
private T name;
public Info(T name){
this.name = name;
}
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
}
public class ConstructionDemo {
public static void main(String[] args) {
Info<String> f = new Info<String>("hello");
fun(f); //引用传递,会报错
}
public static void fun(Info<Object> f){ //无法使用Object类接收,会报错
System.out.println(f);
}
}
以上程序中,尽管String 是 Object 类的子类,但是在进行泛型操作时,程序是无法正确执行的。
例如:Info<String> 不能使用Info<Object>接收,因为这表示扩大了子类的内容。
所以,Java中引入了通配符 “?”,表示可以接收此类型的任意泛型对象,修改代码如下:
class Info<T>{
private T name;
public Info(T name){
this.name = name;
}
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
}
public class ConstructionDemo {
public static void main(String[] args) {
Info<String> f = new Info<String>("hello");
fun(f);
}
public static void fun(Info<?> f){ //使用通配符接收
System.out.println(f.getName());
}
}
程序运行结果:
注意:使用通配符接收时泛型对象时,只能输出对象内容,不能对修改对象
class Info<T>{
private T name;
public Info(T name){
this.name = name;
}
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
}
public class ConstructionDemo {
public static void main(String[] args) {
Info<String> f = new Info<String>("hello");
fun(f);
}
public static void fun(Info<?> f){ //使用通配符接收
f.setName("world"); //不可修改内容
System.out.println(f.getName());
}
}
程序编译报错:
二 、受限泛型
在引用传递中,在泛型操作中,可以设置一个泛型对象的范围上限和范围下限。范围上限使用 extends 关键字声明,范围下限使用 super 关键字进行声明
【设置上限格式】
声明对象:类名称<? extends 类> 对象名称
定义类:[访问权限] 类名称<泛型标识 extends 类>{ }
【设置下限格式】
声明对象:类名称<? super类> 对象名称
定义类:[访问权限] 类名称<泛型标识 extends 类>{ }
1 、泛型的上限
class Info<T>{
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){ // 直接打印
return this.var.toString() ;
}
};
public class GenericsDemo17{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 声明Integer的泛型对象
Info<Float> i2 = new Info<Float>() ; // 声明Float的泛型对象
i1.setVar(20) ; // 设置整数,自动装箱
i2.setVar(20.5f) ; // 设置小数,自动装箱
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<? extends Number> temp){ // 只能接收Number及其Number的子类
System.out.print(temp + "、") ;
}
};
程序运行结果:
以上程序,fun()方法只能接收Number类型的Info类的泛型对象,如果此时传递的是一个String类的泛型对象,则编译时出现错误
class Info<T>{
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){ // 直接打印
return this.var.toString() ;
}
};
public class GenericsDemo17{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 声明Integer的泛型对象
i1.setVar("hello") ;
fun(i1) ;
}
public static void fun(Info<? extends Number> temp){ // 只能接收Number及其Number的子类,编译错误
System.out.print(temp + "、") ;
}
};
程序编译错误:
2 、泛型的下限
class Info<T>{
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){ // 直接打印
return this.var.toString() ;
}
};
public class GenericsDemo21{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 声明String的泛型对象
Info<Object> i2 = new Info<Object>() ; // 声明Object的泛型对象
i1.setVar("hello") ;
i2.setVar(new Object()) ;
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<? super String> temp){ // 只能接收String或Object类型的泛型
System.out.print(temp + "、") ;
}
};
程序运行结果:
同样,如果传递的类型不对,也将出现编译错误
class Info<T>{
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){ // 直接打印
return this.var.toString() ;
}
};
public class GenericsDemo22{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 声明Integer的泛型对象
i1.setVar(30) ;
fun(i1) ;
}
public static void fun(Info<? super String> temp){ // 只能接收String或Object类型的泛型
System.out.print(temp + "、") ;
}
};
程序编译错误: