美文网首页
Java泛型详解

Java泛型详解

作者: Tinyspot | 来源:发表于2022-07-19 14:17 被阅读0次

1. 泛型多边界

  • 语法 <T extends A & B & C>
  • 一个 class 边界 + 多个接口边界
  • 第一个是类,& 后面的只能是接口(即:单继承 多实现)

https://developer.aliyun.com/article/24356
https://www.jianshu.com/p/0f2a9b9afde4

2. 泛型类派生子类

// 2.1 子类也是泛型,子类和父类的泛型标识要一致
public class ResultDTO<T, S> extends Result<T, S> {
}
ResultDTO<QueryDTO, QueryVO> resultDTO = new ResultDTO<>();

// 2.2 子类不是泛型类,父类要明确泛型的数据类型
public class ResultDTO extends Result<QueryDTO, QueryVO> {
}
ResultDTO resultDTO = new ResultDTO();

3. 获取泛型参数类型

3.1 继承泛型类

public class Result<T, S> {
}
public class ResultDTO extends Result<QueryDTO, QueryVO> {
}

public static void main(String[] args) {
    ParameterizedType parameterizedType = (ParameterizedType) ResultDTO.class.getGenericSuperclass();
    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    for (Type genericParameterType : actualTypeArguments) {
        // 注意 genericParameterType.getClass() 是得到 class 文件信息,不能使用这种方式
        Class clazz = (Class) genericParameterType;
    }
    Class<QueryDTO> queryDTOClass = (Class<QueryDTO>) actualTypeArguments[0];
    Class<QueryVO> queryVOClass = (Class<QueryVO>) actualTypeArguments[1];
    String beanName = queryVOClass.getName();
    String className = queryVOClass.getSimpleName();
}

3.2 实现泛型接口

public interface Result<T, S> {
}
public class ResultDTO implements Result<QueryDTO, QueryVO> {
}

public static void main(String[] args) {
    /**
     * Type[] genericInterfaces = ResultDTO.class.getGenericInterfaces();
     * Type[] 数组,代表类实现的多个接口
     * ResultDTO implements Result<QueryDTO, QueryVO> {} 只实现了一个接口,取第一个元素
     */
    Type genericInterface = ResultDTO.class.getGenericInterfaces()[0];
    ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
    Class<QueryDTO> queryDTOClass = (Class<QueryDTO>) actualTypeArguments[0];
    String beanName = queryDTOClass.getName();
}

4. 泛型擦除

Java 泛型是 1.5 引入,为了兼容 1.5 之前的代码,在编译器里通过擦除来支持泛型

例如:

List<Integer> intList = new ArrayList<>();
List<String> strList = new ArrayList<>();
// intList.getClass().getName() 和 strList.getClass().getName() 都是 java.util.ArrayList
System.out.println(intList.getClass() == strList.getClass()); // true

List<String>.class、List<Integer>.class 在 JVM 层面只有 List.class

// public TypeVariable<Class<T>>[] getTypeParameters() {}
List<User> users = new ArrayList<>();
System.out.println(Arrays.toString(users.getClass().getTypeParameters())); // [E]

getTypeParameters 返回类型参数,查看上面并不是返回 Integer,而是 [E] (一个占位符)

编译后查看 class 文件
进入class目录 javap -v xxx.class or javap -v xxx(文件后缀.class可省略)

List<Person> list = new ArrayList<>();
// javap 编译后,泛型 Person 被擦除 (泛型Person 并不是字节码中的指令,只是个符号,编译后被擦除)

 Code:
      stack=2, locals=2, args_size=1
         0: new     #2    // class java/util/ArrayList(编译后只是 ArrayList)

References

相关文章

  • 泛型,复习

    Java泛型详解:和Class的使用。泛型类,泛型方法的详细使用实例 - LZJWXJ树袋熊 - CSDN博客

  • java 泛型

    java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

  • 泛型

    java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一Java泛型深入理解加泛型面试数组的协变性与范型的不可变性

  • 详解Java泛型之4——一个例子理解泛型带来的好处

    前面我介绍了关于泛型、通配符以及泛型擦除的相关知识点,大家可以参考以下文章: 详解Java泛型之1——入门泛型必懂...

  • 详解Java泛型之3——十分钟理解泛型擦除

    前面我们介绍了泛型以及通配符的基础概念,可以参考文章: 详解Java泛型之1——入门泛型必懂的知识点[https:...

  • java泛型详解

    java泛型详解 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。 什...

  • Java泛型、枚举类型详解

    建议看以下博客文章,比较详细且易懂 Java泛型详解 java 枚举(enum) 全面解读

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 2018-07-16

    Java 阅读 大白话说Java泛型 深入理解Java集合框架 java构造代码块详解 Java中Overload...

  • 泛型程序设计

    诚心推荐这一篇文章更好 java 泛型详解 泛型程序设计 泛型意味着编写的代码可以被不同类型重用 ArrayLis...

网友评论

      本文标题:Java泛型详解

      本文链接:https://www.haomeiwen.com/subject/vpcdirtx.html