泛型擦除是什么?

泛型擦除(Type Erasure)是Java编译器在编译泛型代码时的一种机制,它的目的是确保泛型能够与JAVA的旧版本(即不支持泛型的版本)兼容。泛型擦除会在编译时移除泛型类型信息,并将泛型类型替换为其非泛型的上限类型(通常是Object)

详细解释

在Java中,泛型信息只存在于源代码和编译时,在运行时,所有的泛型类型信息都会被擦除。这意味着在运行时,所有泛型类型都被替换为它们的上限类型(如果没有指定上限,则默认为Object).

示例

考虑一个简单的泛型类:

java 复制代码
public class Box<T> {
    private T value;
    
    public void setValue(T value) {

        this.value = value;
    }

    public T getValue(){
        return value;

    }


}

在编译时,泛型类型T会被擦除,并替换为它的上限类型。在这个例子中,因为,没有指定上限类型,T会被替换为uObject。编译后的代码大致如下:

java 复制代码
public clss Box {
    private Object value;

    public void setValue(Object Value){
        this.value = value;
    }


    public Object getValue(){
        return value;
    }
}

类型擦除的影响

1.运行时类型检查:由于泛型类型信息在运行时被擦除,无法在运行时回去泛型类型的信息。例如,不能使用instanceof操作符检查泛型类型。

java 复制代码
Box<String> stringBox = new Box<>();
if (stringBox instanceof Box<String>) { // 编译错误
    // ...
}
  1. 泛型数组:不能创建泛型类型的数组,因为在运行时无法确定泛型类型。
java 复制代码
List<String>[] stringLists = new List<String>[10]; // 编译错误
  1. 类型安全:在编译时进行类型检查,确保类型安全。然而,由于类型擦除,在某些情况下仍可能出现类型转换异常。
java 复制代码
List<String> stringList = new ArrayList<>();
List rawList = stringList; // 允许,但不安全
rawList.add(123); // 编译时不报错,但运行时可能导致问题
String str = stringList.get(0); // 运行时抛出ClassCastException

限制

  1. 静态上下文中使用泛型:不能在静态字段或静态方法中使用类型参数,因为类型参数是在实例化时才指定的,而静态成员与具体实例无关。
java 复制代码
public class GenericClass<T> {
    private static T value; // 编译错误
    
    public static T staticMethod(T param) { // 编译错误
        return param;
    }
}
  1. 泛型实例化:不能直接实例化泛型类型,因为在运行时泛型类型信息已经被擦除。
java 复制代码
public class GenericClass<T> {
    public void createInstance() {
        T obj = new T(); // 编译错误
    }
}
相关推荐
xieliyu.2 分钟前
【JavaEE进阶】Spring Boot 日志:从 System.out 到 @Slf4j,6 个级别 + 4 类配置一篇讲透
java·spring boot·spring·java-ee·springboot·logback·slf4j
IT_Octopus39 分钟前
Apollo 配置中心入门:一所“小学校“读懂 Portal、Meta Server、Config Service
java·后端·spring
cfm_291441 分钟前
偏向锁的Epoch优化机制
java
CRMEB系统商城1 小时前
家电零售的供应商协同与物流提效
java·开发语言·人工智能·小程序·1024程序员节
jason.zeng@15022071 小时前
Nginx 配置详解(静态 HTML、下载目录、API 反向代理三套场景)
java·vue.js·1024程序员节
鬼手点金1 小时前
从 API 消息到模型 Token:Chat Template
java·前端·javascript·数据库·人工智能·深度学习·1024程序员节
Shadow(⊙o⊙)1 小时前
LangChain 自定义工具全解析:从 @tool 到 bind_tools 的完整调用链路
java·服务器·前端·1024程序员节
王大师王文峰1 小时前
Java+AI 面试题(二):业务场景设计 10 例【客服机器人、合同审查、Text2SQL、告警降噪、成本优化】场景题答法与追问链路
java·开发语言·人工智能
言乐61 小时前
Python实现三轴联动根据数据自动打磨镜片模型
开发语言·python
CHHH_HHH2 小时前
【Linux网络篇】初识网络与Socket编程基础
linux·服务器·c语言·开发语言·网络·后端·1024程序员节