温馨提示:
本文最后更新于 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();