java泛型中的通配符 T,E,K,V,?

2023-02-01 14:44:45 浏览数 (1)

温馨提示:

本文最后更新于 2022年12月30日,已超过 31 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。

java泛型

java泛型(generics)是jdk5引入的新特性,泛型提供了编译时类型安全检测机制,该机制运行开发者在编译时检测到非法的类型.

泛型的本质是参数化类型,也就是说,将所操作的数据类型作为一个参数传递,通过这个类型参数,就能识别这个变量的类型

代码语言:javascript复制
public class TestGeneric<T> {
    private T t;
    public void setT(T t) {this.t = t;}
    public T getT() {return t;}
    public static void main(String[] args) {
        //这里直接指定String作为参数类型
        TestGeneric<String> testGeneric = new TestGeneric<>();
        //setT时,T就是String
        testGeneric.setT("test");
        //可以直接打印getT(),默认为String
        System.out.println(testGeneric.getT());
    }
}

泛型中的通配符

在正常情况下,只要是满足常量命名的字符串,都可以作为通配符使用,例如:T,E,K,V,A1,A1111111111,等等,但是通配符肯定不会需要用到这么多,不管是什么字符,都是代表着 "通配符",所以一般会一些有意义的字母,来表示不一样的通配符.

  • K和V 表示key,value,比如用于map的通配符
  • T(type) 表示具体的一个java类型
  • E (element) 表示一个元素,例如List

除了这几个特定意义的通配符之外,还存在 ? 无界通配符,这个东西一般会在方法参数上使用,搭配 <T extends E><T super E> 使用

上界通配符 <T extends E>

该符号表示,在参数中,传入的类型必须是E或者继承与E的子类,在使用时,可以使用E的方法

代码语言:javascript复制
    public static void main(String[] args) {
        //这里直接指定String作为参数类型
        TestGeneric<String> testGeneric = new TestGeneric<>();
        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("a",1);
        Map map = testGeneric.test(hashMap);
        System.out.println(map.get("a"));
    }
    public <E extends Map> E test( E e) {
        return e;
    }

可以看出,在test方法中,传入了hashmap(实现了Map接口),可以正常使用 如果有多个类型参数,则使用逗号分隔即可

下界通配符<? super E>

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

代码语言:javascript复制
private <T> void test(List<? super T> dst, List<T> src){
    for (T t : src) {
        dst.add(t);
    }
}

public static void main(String[] args) {
    List<Dog> dogs = new ArrayList<>();
    List<Animal> animals = new ArrayList<>();
    new Test3().test(animals,dogs);
}
// Dog 是 Animal 的子类
class Dog extends Animal {

}

特殊的?通配符

在上面我们可以看到,上界通配符是 <T extends E>,下界通配符确是<? super E>

?和T都表示不确定的类型,区别在于一个是字母,可以直接操作,但是对? 不能直接操作,比如:

代码语言:javascript复制
// 可以
T t = operate();

// 不可以
?car = operate();

0 人点赞