• Java泛型


    目录

    泛型是什么

    为什么要使用泛型

    泛型有哪些

    怎么用泛型 


    泛型是什么

    Java泛型(generics)是JDK5开始引入的一个新特性,指所操作的数据类型被指定为一个参数。

    为什么要使用泛型

    在没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这本身就是一个安全隐患。那么泛型的好处就是在编译的时候能够检查类型安全,并且所有的强制转换都是自动和隐式的。

    泛型有哪些

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

    怎么用泛型 

    ?无界通配符

    1. 有一个父类Animal和N个子类:
    2. static int countLegs (List animals ) {
    3. int retVal = 0;
    4. for (Animal animal : animals){
    5. retVal += animal.countLegs();
    6. }
    7. return retVal;
    8. }
    9. static int countLegs1 (List animals){
    10. int retVal = 0;
    11. for (Animal animal : animals ){
    12. retVal += animal.countLegs();
    13. }
    14. return retVal;
    15. }
    16. public static void main(String[] args) {
    17. List dogs = new ArrayList<>();
    18. // 不会报错
    19. countLegs( dogs );
    20. // 报错
    21. countLegs1(dogs);
    22. }

    对于不确定要操作的类型,可以使用无限制通配符(即 ),表示可以持有任何类型。像countLegs方法中,限定了上界,但是不关心具体类型是什么,所以对于传入的Animal的所有子类都可以支持,而countLegs1 就不行。

    上界通配符 < ? extends E>

    上届:用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类。在类型参数中使用extends表示这个泛型中的参数必须是E或者E的子类,这样有两个好处:

    1. 如果传入的类型不是E 或者 E 的子类,编译不成功
    2. private extends A, E extends B> E test(K arg1, E arg2){
    3. E result = arg2;
    4. arg2.compareTo(arg1);
    5. //.....
    6. return result;
    7. }
    8. 类型参数列表中如果有多个类型参数上限,用逗号分开

    下界通配符 < ? super E>

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

    1. private void test(Listsuper T> dst, List src){
    2. for (T t : src) {
    3. dst.add(t);
    4. }
    5. }
    6. public static void main(String[] args) {
    7. List dogs = new ArrayList<>();
    8. List animals = new ArrayList<>();
    9. new Test3().test(animals,dogs);
    10. }
    11. // Dog 是 Animal 的子类
    12. class Dog extends Animal {
    13. }

    dst类型 “大于等于” src 的类型,这里的“大于等于”是指 dst 表示的范围比 src 要大,因此装得下 dst 的容器也就能装 src 。

    ?和 T 的区别

    T 是一个确定的类型,通常用于泛型类和泛型方法的定义,?是一个 不确定 的类型,通常用于泛型方法的调用代码和形参,不能用于定义类和泛型方法。比如如下这种 :

    区别1:通过T来确保泛型参数的一致性

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

    区别2:类型参数可以多重限定而通配符不行

    1. public class Multilimit implements MultilimitInterfaceA,MultilimitInterfaceB{
    2. //使用&符号设定多重边界
    3. public staticextends MultilimitInterfaceA & MultilimitInterfaceB> void test(T t){
    4. }
    5. }
    6. interface MultilimitInterfaceA{}
    7. interface MultilimitInterfaceB{}

     区别3:通配符可以使用超类限定而类型参数不行 类型参数 T只具有一种类型限定方式:

    T extends A
    

    但是通配符 ? 可以进行 两种限定:

    1. ? extends A
    2. ? super A

    Class和 Class区别

    常见的是在反射场景下的使用

    1. // 通过反射的方式生成multiLimit对象
    2. MultiLimit multiLimit = (MultiLimit)
    3. Class.forName("com.glmapper.bridge.boot.generic.MultiLimit").newInstance();
    4. 对于上述代码,在运行期,如果反射的类型不是MultiLimit类,那么一定会报
    5. ava.lang.ClassCastException错误。
    6. Class在实例化的时候,T 要替换成具体类。Class它是个通配泛型,? 可以代表任何类型,
    7. 所以主要用于声明时的限制情况。
  • 相关阅读:
    数学建模经验分享会For浙商大管工学院
    【MySQL】MySQL 服务无法启动。服务没有报告任何错误。请键入 NET HELPMSG 3534 以获得更多的帮助。
    iOS CGRect CGPoint NSRange等结构体的NSLog打印输出
    记一次WPF集成SemanticKernel+OneAPI+讯飞星火认知大模型实践
    用豆瓣电影和掌桥科研练习网页解析的三种方式——正则、Xpath和bs4
    Kafka介绍、安装以及原理解析
    基于Android studio英语背单词系统java
    太赞了,300+图解Pandas,超级用心的教程!
    git版本管理的使用
    系统设计:消灭慢接口
  • 原文地址:https://blog.csdn.net/xing_jian1/article/details/134504406