Java如何获取泛型的实际类型?

本文介绍了在Java中通过特定的设计模式来获取泛型参数的实际类型的方法,并对比了Kotlin等语言的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有人问以下情况如何得到泛型参数的实际类型:

APIService api = new APIService<User>();

由于Java的类型擦除,没有办法获取,APIService不知道它被赋予了User。

但可以变通一下:

APIService api = APIService.create(User.class);

对应的类定义是:

public class APIService<T> {
  public static <U> APIService<U> create(Class<U> cls) {
    return new APIService<U>(cls);
  }

  public APIService(Class<T> cls) {
    //这里知道了实际类型cls
  }
}

Kotlin, Scala等基于JVM的语言具有reified generics,能方便地获取实际类型。

### Java 概念及其作用 Java中的提供了一种安全的方式来处理对象集合,允许编写能够操作多种数据类型的通用算法。通过引入类型参数`T`来表示不确定的具体类型,在定义类、接口或方法时可以不绑定到特定的数据类型[^1]。 #### 优点 - **类型安全性**:减少了强制转换的需求并防止运行时期间可能出现的ClassCastException异常。 - **可重用性和灵活性**:使得代码更加灵活多变,适用于不同种类的对象而无需重复编码逻辑。 ### 类型擦除原理 类型擦除是指在编译期间移除了所有关于实际使用的具体类型的信息,并将其替换为最接近公共父级(通常是Object)。这意味着一旦经过编译期之后,虚拟机中就不存在任何有关于实际类型信息了;相反地,所有的实例都被视为它们各自的原始类型[^3]。 这种设计决策有助于保持向后兼容性的同时简化字节码结构,因为旧版本JVM并不支持语法特性。然而这也意味着无法创建带有确切参数化的数组(`new ArrayList<String>[10]`),并且不允许静态字段依赖于类型变量。 ### 限制 由于存在上述提到的类型擦除过程,因此有一些重要的约束条件需要注意: - **不能使用基本数据类型作为类型实参**:比如`ArrayList<int>`是非法语句,应该改写成包装类形式如`ArrayList<Integer>`. - **无法实例化类型参数**:即像`t=new T();`这样的表达式会被认为错误,除非借助反射API. - **构造函数也不能接受未限定的通配符**, 即`<?>`仅限于局部变量声明或者方法签名内. ### 常用通配符 为了增强系统的表达能力,Java提供了两种主要类型的通配符:“?”代表未知类型,“extends”和“super”则用来指定上下边界范围: - `?`: 表达任意未知类型, 可以读取但不可修改容器内的元素 (只读). ```java List<?> list = new ArrayList<>(); Object obj = list.get(0); // OK: Reading is allowed ``` - `? extends Type`: 定义了一个上限继承关系链表,表明此位置上的类型要么就是Type本身或者是它的某个子类别成员之一 ```java List<? extends Number> numbers; Integer i = numbers.get(0); // Possible if the actual type argument is Integer or its subclass ``` - `? super Type`: 设定了下限超类关联列表,说明此处所指代的是Type或是更广的祖先节点 ```java List<? super Integer> integersOrSuperTypes; integersOrSuperTypes.add(new Integer(5)); // Adding an element of lower bound type is safe ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值