0

在 Java 中,泛型类型在编译时被删除,而是Object替换所有泛型参数并完成隐式转换。这样做的原因是为了保持向后兼容性,如此所述。任何人都可以在 Java 1.5 之前的版本中给出一个代码示例,如果 Java 1.5 没有在编译时擦除类型,那么它会在运行时导致问题吗?

4

1 回答 1

1

我认为您误解了类型擦除的目的,首先- 类型擦除并不是为了避免运行时异常(但它是为了避免任何运行时性能损失,更多信息即将到来......其次- 在 Java SE 5 之前有没有“泛型”,所以不存在“类型擦除”的问题。

在此处阅读有关类型擦除的目的:

泛型被引入 Java 语言以在编译时提供更严格的类型检查并支持泛型编程。为了实现泛型,Java 编译器将类型擦除应用于:

  • 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或 Object。因此,生成的字节码只包含普通的类、接口和方法。
  • 必要时插入类型转换以保持类型安全。
  • 生成桥方法以保留扩展泛型类型中的多态性。

类型擦除确保不会为参数化类型创建新类;因此,泛型不会产生运行时开销

因此,泛型中“类型擦除”的主要目的之一是避免任何运行时性能损失,因为所有类型参数都在编译时根据类型参数解析和验证,因此在运行时 JVM 需要为此浪费任何 CPU 周期。

见下面的代码,它表明编译后类型被解析,最终被 JVM 解释的字节码不会留下任何类型参数。

编译前:

import java.util.Arrays;
import java.util.List;

public class TypeErasureExample {
    public static void main(String[] args) {
        List<String> stringList = Arrays.asList(new String[]{"a", "b", "c"});
        List<?> numberList = Arrays.asList(new Integer[]{1, 2, 3});

        System.out.println(stringList);
        System.out.println(numberList);
    }
}

编译后(反编译的o/p):

import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

public class TypeErasureExample
{
  public static void main(String[] paramArrayOfString)
  {
    List localList1 = Arrays.asList(new String[] { "a", "b", "c" }); // Notice "List<String>" is converted to "List", this is what type erasure does.
    List localList2 = Arrays.asList(new Integer[] { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }); // Notice "List<?>" is converted to "List", this is what type erasure does.

    System.out.println(localList1);
    System.out.println(localList2);
  }
}
于 2017-05-08T01:33:59.803 回答