在Java中,泛型类型在编译时被擦除,而Object
代替所有泛型参数,并完成隐式转换。这样做的原因是为了保持向后兼容性,如here所述。任何人都可以在Java 1.5之前提供代码示例,如果Java 1.5在编译时没有擦除类型,那么这会在运行时引起问题吗?
答案 0 :(得分:1)
我认为你误解了类型擦除的目的,首先 - 类型擦除并不是为了避免运行时异常(,但它意味着避免任何运行时性能损失,更多信息即将到来...... )和其次 - 在Java SE 5之前没有“泛型”,因此不存在“类型擦除”的问题。
阅读here关于类型擦除的目的:
泛型被引入Java语言以提供更紧密的类型 在编译时检查并支持通用编程。至 实现泛型,Java编译器将类型擦除应用于:
- 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或对象。生成的字节码, 因此,只包含普通的类,接口和方法。
- 如有必要,插入类型转换以保护类型安全。
- 生成桥接方法以保留扩展泛型类型中的多态性。
类型擦除确保不会为参数化创建新类 类型;因此,泛型不会产生运行时开销。
因此,泛型中“类型擦除”的主要目的之一是避免任何运行时性能损失,因为所有类型参数在编译时都会根据类型参数进行解析和验证,因此在运行时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);
}
}