"T"是定义类或方法时声明的东西,"?"是调用时传入的东西,二者是不同的概念。

Class<T>在实例化的时候,T要替换成具体类
Class<?>它是个通配泛型,?可以代表任何类型

<? extends T>受限统配,表示T的一个未知子类
<? super T>下限统配,表示T的一个未知父类

 

Java 泛型中<?>和<T> 区别

java泛型的两种用法:List<T>是泛型方法,List<?>是限制通配符

List<T>一般有两种用途:

1、定义一个通用的泛型方法
伪代码:

public interface Dao{
  List<T> getList(){};
}

List<String> getStringList(){
  return dao.getList(); //dao是一个实现类实例
}

List<Integer> getIntList(){
  return dao.getList();
}

上面接口的getList方法如果定义成List<?> ,后面就会报错。

 

2、限制方法的参数之间或参数和返回结果之间的关系。

List<T> getList<T param1,T param2>

这样可以限制返回结果的类型以及两个参数的类型一致。

List<?>一般就是在泛型起一个限制作用。
伪代码:

public Class Fruit(){}

public Class Apple extends Fruit(){}

public void test(? extends Fruit){};

test(new Fruit());
test(new Apple());
test(new String()); //这个就会报错

这样可以现在test方法的参数必须是Fruit或其子类

以上都是个人平时使用这两个的一些经验和理解,可能有不全面的地方。

 

?和T都表示不确定的类型  

public static void printColl(ArrayList<?> al){
Iterator<?> it = al.iterator();
while(it.hasNext()){
	System.out.println(it.next().toString());
}

但如果是T的话 函数里面可以对T进行操作 比如while里面可以这样写

T t = it.next();

System.out.println(t);

 

T自定义泛型和?通配符泛型

1.在整个类中只有一处使用了泛型,使用时注意加了泛型了参数不能调用与参数类型有关的方法比如“+”,比如打印出任意参数化类型集合中的所有内容,就适合用通配符泛型<?>

public static void printCollecton(Collection <?> collection) {
for(Object obj: collection) {
		System.out.println(obj);
	}
}

2. 当一个类型变脸用来表达两个参数之间或者参数与返回值之间的关系时,即统一各类型变量在方法签名的两处被使用,或者类型变量在方法体代码中也被使用而不仅 仅在签名的时候使用,这是应该用自定义泛型<T>。泛型方可以调用一些时间类型的方法。比如集合的add方法。

public static <T> T autoConvertType(T obj) {
   return(T)obj;
}

 

泛型三种:

1) ArrayList<T> al=new ArrayList<T>(); 指定集合元素只能是T类型

2) ArrayList<?> al=new ArrayList<?>(); 集合元素可以是任意类型,这种没有意义,一般是方法中,只是为了说明用法

3) ArrayList<? extends E> al=new ArrayList<? extends E>();

泛型的限定:

? extends E:接收E类型或者E的子类型

?super E:接收E类型或者E的父类型

 

 

参考推荐

List<?>和List<T>的区别

Java 泛型 <? super T> 中 super 怎么 理解?与 extends 有何不同