Java中泛型是在不确定具体使用哪个类型的时候进行的泛型处理,这样可以匹配多个数据类型。
而通配符 ? 是一种泛型的手段,通过一个占位符,将所需要的数据类型,不显示的说明,只是在那里模糊的占位,表示有那么一个类型。这样在我们使用泛型时,不管是定义函数还是类,都可以轻松的使用泛型。
泛型的限定:在于将泛型的通配符的作用域减小,本来泛型的通配符的作用域作用于所有的类型,但是有了限定可以将作用域大大减小,方便我们的功能实现。
具体可以分为,向上,向下
向上:
? extends E: 可以接收E 类型或者是E类型的子类型
向下:
? super E 可以接收 E类型 或者是E类型的父类型
下面使用一段代码来进行说明和比较,这样比较直观,可以更好的看出他们的区别:
package mypack;
/**
* 泛型限定:
* ? 通配符 :也可以理解为占位符
* 泛型的限定:
* ? extends E: 可以接收E 类型或者是E类型的子类型
* ? super E 可以接收 E类型 或者是E类型的父类型
*/
import java.util.ArrayList;
import java.util.Iterator;
public class Fanxingxiand {
public static void main(String[] args) {
ArrayList<Persons> persons = new ArrayList<Persons>();
persons.add(new Persons("aaa"));
persons.add(new Persons("bbb"));
persons.add(new Persons("ccc"));
//打印父类
print1(persons);
print2(persons);
print3(persons);
ArrayList<Student> students = new ArrayList<Student>();
students.add(new Student("111"));
students.add(new Student("333"));
students.add(new Student("222"));
//打印子类
//print(students); 是错误的,print函数是父类的,比较大,子类不能使用
print1(students);
print2(students);
print3(students);
//打印无关类
ArrayList<Dogs> dogs = new ArrayList<Dogs>();
dogs.add(new Dogs("dog1"));
dogs.add(new Dogs("dog2"));
dogs.add(new Dogs("dog3"));
dogs.add(new Dogs("dog4"));
print1(dogs); //可以打印
//print2(dogs); //编译出错不能打印
//print3(dogs); //编译出错不能打印
}
/*
第一种 : 只能打印父类的、
public static void print(ArrayList<Persons> persons){
Iterator<Persons> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());
}
}*/
/*第二种,打印所有
* 可以都讲他们打印出来,但是这个是将什么类型的元素都可以打印出来
* */
public static void print1(ArrayList<?> persons){
Iterator<?> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
/*
* 3 。 泛型限定,作用是可以只能打印 Persons 和其子类的的数据 ,其他不能打印。
* */
public static void print2(ArrayList<? extends Persons> persons){
Iterator<? extends Persons> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
public static void print3(ArrayList<? super Student> persons){
Iterator<? super Student> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
class Persons {
private String name;
Persons(){}
Persons(String name){this.name = name;}
public String getName(){
return name;
}
@Override
public String toString() {
return "Persons [name=" + name + "]";
}
}
class Student extends Persons{
Student(){}
Student(String name){super(name);}
}
class Dogs{
private String name;
Dogs(){}
Dogs(String name){this.name = name;}
public String getName(){
return name;
}
@Override
public String toString() {
return "Dogs [name=" + name + "]";
}
}