为什么Java中的泛型是伪泛型?

目录

一、什么是泛型?

二、为什么说是伪泛型?

2.1 类型擦除(Type Erasure)

2.2 Java选择伪泛型的原因

2.3伪泛型的局限性

三、总结


一、什么是泛型?

泛型是Java编程语言中的一个重要特性,它允许类、接口和方法在定义时使用一个或多个类型参数,这些类型参数在使用时可以被指定为具体的类型。

泛型的主要目的是在编译时提供更强的类型检查,并在编译后能够保留类型信息,避免了在运行时出现类型转换异常。

为什么需要泛型?

  •  适用于多种数据类型执行相同的代码,如一下实例。
private static int add(int a, int b) {
    System.out.println(a + "+" + b + "=" + (a + b));
    return a + b;
}

private static float add(float a, float b) {
    System.out.println(a + "+" + b + "=" + (a + b));
    return a + b;
}

如果没有泛型,要实现不同数据类型的加法,那只能通过定义不同的方法来实现,如果引入泛型,我们可以复用一个方法:

privat static <T extends Number> add(T a, T b) {
    System.out.printlen(a + "+" + b + "=" + (a + b));
    return a + b;
}

泛型中的类型在使用时指定,不需要强制类型转换(类型安全, 编译器会检查类型)

如下例子:

List list = new ArrayList();
list.add("jerry");
list.add(new Person());
list.add(123);

上述例子中,list中的类型都是Object,无法约束其中的类型,所以在取出类型的时候需要认为进行强制类型转换为目标类型,很容易出现java.lang.ClassCastException异常。

引入泛型后:

List<String> list = new ArrryList<>();
// list中只能存储String类型的数据,不能放其他类型的数据。

二、为什么说是伪泛型?

回顾完什么是泛型后,我们来讲为什么Java中的泛型是伪泛型。

2.1 类型擦除(Type Erasure)

Java中的泛型被称为伪泛型,主要是因为Java的泛型是通过**类型擦除(Type Erasure)**实现的,而不是像某些其他语言(如C#)那样在运行时保留泛型类型信息。

Java的泛型在编译后会进行类型擦除,即所有泛型类型参数都会被替换为它们的上限类型(通常是Object),或者指定的边界类型(如extends SomeClass)。这意味着在运行时,泛型类型信息会被擦除,无法直接获取。

List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();

// 编译后,两者的类型都会被擦除为原始类型 List
System.out.println(stringList.getClass() == integerList.getClass()); // 输出 true

在运行时,stringListintegerList的类型都是List,而不是List<String>List<Integer>

2.2 Java选择伪泛型的原因

Java选择使用类型擦除来实现泛型,主要是为了向后兼容简化迁移

  • 向后兼容:Java在引入泛型(Java 5)之前已经存在大量的非泛型代码(如ArrayListHashMap等)。通过类型擦除,泛型代码可以与旧的非泛型代码兼容。

  • 简化迁移:类型擦除使得旧代码可以逐步迁移到泛型,而不需要重写所有代码。

2.3伪泛型的局限性

由于类型擦除,Java的泛型存在一些局限性:

  • 无法获取泛型的实际类型参数

List<String> list = new ArrayList<>();
System.out.println(list.getClass().getTypeParameters()); // 输出 [E],而不是 String
  • 无法创建泛型类型的实例

    public static <T> T createInstance(Class<T> clazz) {
        return new T(); // 编译错误:无法创建泛型类型的实例
    }
  • 无法使用基本类型作为泛型参数

List<int> list = new ArrayList<>(); // 编译错误:必须使用包装类型
List<Integer> list = new ArrayList<>(); // 正确

三、总结

Java的泛型被称为伪泛型,主要是因为:

  • 通过类型擦除实现,泛型类型信息在运行时不可用。

  • 设计目的是为了向后兼容简化迁移

  • 存在一些局限性,但可以通过其他方式(如反射)部分解决。

尽管是伪泛型,Java的泛型仍然提供了强大的类型安全性和代码复用能力,是Java语言中不可或缺的特性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值