Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 原始类型和子类型_Java_Compiler Construction_Raw Types - Fatal编程技术网

Java 原始类型和子类型

Java 原始类型和子类型,java,compiler-construction,raw-types,Java,Compiler Construction,Raw Types,我们有通用类 SomeClass<T>{ } SomeClass{} 我们可以这样写: SomeClass s= new SomeClass<String>(); SomeClass s=newsomeclass(); 没关系,因为原始类型是泛型类型的超类型。但是 SomeClass<String> s= new SomeClass(); SomeClass s=newsomeclass(); 这是正确的。为什么它是正确的?我以为是在进行类型检查之

我们有通用类

SomeClass<T>{ }
SomeClass{}
我们可以这样写:

SomeClass s= new SomeClass<String>();
SomeClass s=newsomeclass();
没关系,因为原始类型是泛型类型的超类型。但是

SomeClass<String> s= new SomeClass();
SomeClass s=newsomeclass();
这是正确的。为什么它是正确的?我以为是在进行类型检查之前进行了类型擦除,但这是错误的

从黑客指南到Javac 当使用默认编译策略调用Java编译器时,它将执行以下过程:

  • 解析:读取一组*.java源文件并映射生成的令牌 将序列插入AST节点
  • 输入:在符号表中输入定义的符号
  • 处理注释:如果需要,处理在中找到的注释 指定的编译单元
  • 属性:属性语法树。此步骤包括名称 分辨率、类型检查和恒定折叠
  • 流:对上一步中的树执行数据流分析。 这包括检查分配和可达性
  • desugar:重写AST并翻译掉一些语法上的糖分
  • 生成:生成源文件或类文件

  • 泛型是语法糖,因此在类型检查之后,在第6遍调用类型擦除,而类型检查在第4遍调用。我很困惑。

    类型参数肯定参与类型检查;否则它将毫无意义(即不比原始类型好)

    生成隐式强制转换时也需要这些信息,这样它将作为调试符号保存到步骤7,并在技术上保存到运行时。但是,只有擦除才会参与运行时类型转换检查(出于明显的向后兼容性原因)。尽管如此,如果您的泛型代码可以进行完全静态检查,那么它可以与非类型擦除语言中的泛型程序一样强大


    当您将
    SomeClass
    分配给
    SomeClass
    时,编译器将向您发出有关原始类型使用的警告。此时,您的程序显然不再安全。

    泛型不是语法糖,SomeClass和SomeClass是微妙的不同类型。允许将原始类型赋值给泛型类型,以支持与旧代码的互操作。@ice phoenix解释了这一点。但是在什么时候调用类型擦除呢?在类型检查之前的第2步或第4步?第7步,生成JVM字节码时删除泛型,编译器总是知道变量的完整泛型类型。@ice phoenix第7步,据我所知,这不是真的。看,我认为,这是第4步,在类型检查之后。看见