java泛型中 ?,T,S,K,字母的区别

在代码中经常会看到这样的函数

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

常用的 T,E,K,V,?

本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T ,在可读性上可能会弱一些。通常情况下,T,E,K,V,? 是这样约定的:

  • ? 表示不确定的 java 类型
  • T (type) 表示具体的一个java类型
  • K V (key value) 分别代表java键值中的Key Value
  • E (element) 代表Element

那么?和具体字母的区别是什么呢

// 通过 T 来 确保 泛型参数的一致性
public <T extends Number> void
test(List<T> dest, List<T> src)

//通配符是 不确定的,所以这个方法不能保证两个 List 具有相同的元素类型
public void test(List<? extends Number> dest, List<? extends Number> src)

? 无界通配符 

对于不确定或者不关心实际要操作的类型,可以使用无限制通配符(尖括号里一个问号,即 <?> ),表示可以持有任何类型

上界通配符 < ? extends E> 

在类型参数中使用 extends 表示这个泛型中的参数必须是 E 或者 E 的子类,这样有两个好处:

  • 如果传入的类型不是 E 或者 E 的子类,编译不成功
  • 泛型中可以使用 E 的方法,要不然还得强转成 E 才能使用

下界通配符 < ? super E>

用 super 进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object

 

下面是例子 

public class FanXing {

    TestA a = new TestA("13");
    TestA b = new TestA(123);

    public void getClass1(TestA<?> test) {

    }
    //报错
    public void getClass2(TestA<T> test) {

    }
}

class TestA<T> {
    private T t;

    public TestA(T key) {
        this.t = key;
    }
}

在使用泛型作为方法的参数时 就需要使用泛型通配符来解除传入参数的类型,类型参数就做不到

<?>与<字母>的还有一个区别就在于   字母形参可以在之后的函数调用  T  t= it.next();

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

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页