1.什么是类型通配符,为什么要使用类型通配符呢?
当要使用泛型类的时候,应该为这个泛型类传入一个类型实参,如果没有传入类型实际参数的时候,编译器就会提出泛型警告。
举个栗子:
public class SymbolForGeneral {
//List<Object> mList
public static void test(List<Object> mList){
for(int i=0;i<mList.size();i++){
System.out.println(mList.get(i));
}
}
public static void main(String[]args){
List<String>list=new ArrayList<>();
list.add("text1");
test(list);
}
}
这段代码是无法运行的,报错点在test(list),因为List<String>并不是List<Object>的子类(如果A是B的一个子类型,而G是一个局具有泛型声明的类或接口,G<A>并不是G<B>的子类型)
为了表示各种泛型List的父类,可以使用类型通配符。类型通配符是一个问号(?),将一个问号作为实参传给List集合,写作List<?>(表示为元素类型未知的List),这个问号被称为通配符,它的元素类型可以匹配任何类型。所以上述代码可以进行修改
public class SymbolForGeneral {
//List<Object> mList
public static void test(List<?> mList){
for(int i=0;i<mList.size();i++){
System.out.println(mList.get(i));
}
}
public static void main(String[]args){
List<String>list=new ArrayList<>();
list.add("text1");
test(list);
}
}
2.设置类型通配符的上限
在限定的条件中,比如说存在着圆,正方形,三角形等,他们都存在于形状类(Shape)中,所以如果要限定List<?>包括在Shape中,使用 List<? extends Shape>即可,在代码作用域使用的所有类型必须以Shape为上限 否则会报错
举个栗子:
import java.awt.*;
/**
* 如何设置通配符的上限
* */
public abstract class Shape {
public abstract void draw(Canvas canvas);
}
public class Rectangle extends Shape {
@Override
public void draw(Canvas canvas) {
System.out.println("在画布"+canvas+"上画一个矩形");
}
}
public class Circle extends Shape{
@Override
public void draw(Canvas canvas) {
System.out.println("在画布"+canvas+"上画一个圆");
}
}
import java.util.List;
public class Canvas {
//设置上限
public void drawAll(List<? extends Shape> mShapeLists){
for(Shape mshape:mShapeLists){
mshape.draw(this);
}
System.out.println("绘制成功");
}
}
public class TestDemo {
public static void main(String[]args){
List<Circle> circleList=new ArrayList<>();
Canvas c=new Canvas();
c.drawAll(circleList);
}
}
3.设置类型实参的上限
用法和上述方法一致,主要是在定义类型形参时设定上限。说明了传给该类型形参的实际类型要不是该上限类型,要不是该上限类型的子类
使用方法:public class Apple<T extends String &java.io.Serializable>
import java.util.List;
/**
* 类型固定
* 设置类型上限
* */
public class Apple<T extends String &java.io.Serializable> {
private T info;
public Apple(){}
public Apple(T info){
this.info=info;
}
public void setInfo(T info){
this.info=info;
}
public T getInfo(){
return info;
}
public void showInfoDetails(){
System.out.println(this.info);
}
public static void main(String[]args){
Apple<String> a1=new Apple<>("苹果");
a1.showInfoDetails();
// Apple<Double>a2=new Apple<>(1.22);
// a2.showInfoDetails();
}
}