我们有通用类
SomeClass<T>{ }
我们可以写一行:
SomeClass s= new SomeClass<String>();
没关系,因为原始类型是泛型类型的超类型。但
SomeClass<String> s= new SomeClass();
是正确的。为什么是正确的?我认为类型擦除是在类型检查之前,但这是错误的。
从黑客指南到 Javac
当使用默认编译策略调用 Java 编译器时,它会执行以下步骤:
- parse:读取一组 *.java 源文件并将生成的令牌序列映射到 AST 节点。
- enter:将定义的符号输入到符号表中。
- 处理注释:如果请求,处理在指定编译单元中找到的注释。
- 属性:属性语法树。此步骤包括名称解析、类型检查和常量折叠。
- flow:对上一步中的树执行数据流分析。这包括检查分配和可达性。
- desugar:重写 AST 并翻译掉一些语法糖。
- generate:生成源文件或类文件。
泛型是语法糖,因此类型擦除在第 6 遍调用,在类型检查之后,在第 4 遍调用。我很困惑。