简体   繁体   English

Java 中 generics 的层次结构信息

[英]Hierarchy information for generics in Java

I understand that while List< Integer> is not a subtype of List< Number> , but it is subtype of List<? extends Number>我知道虽然List< Integer>不是List< Number>的子类型,但它是List<? extends Number> List<? extends Number> . List<? extends Number>

But as Java uses concept of type erasure to implement generics, meaning that we ultimately have single class for all representations, and hence we don't have any class hierarchy defined for such classes in bytecode, then how does Java establishes this hierarchy? But as Java uses concept of type erasure to implement generics, meaning that we ultimately have single class for all representations, and hence we don't have any class hierarchy defined for such classes in bytecode, then how does Java establishes this hierarchy?

Java is not bytecode, it compiles to bytecode. Java 不是字节码,它编译为字节码。 It is precisely because of this that it can be made a more powerful language than bytecode.正因为如此,它才能成为比字节码更强大的语言。

The Java Language is specified in the Java Language Specifications . Java 语言在Java 语言规范中指定。 There will be lots of things in this spec that the JVM doesn't know about. JVM 不知道此规范中的许多内容。 Parameterised types being one of them.参数化类型就是其中之一。 But that's fine, because it is the job of the compiler to translate Java source code to something that the JVM can understand.但这很好,因为编译器的工作是将 Java 源代码转换为 JVM可以理解的内容。 In the case of generic types, this means erasing the generic parameters, and adding lots of casts.对于泛型类型,这意味着删除泛型参数并添加大量类型转换。

hence we don't have any class hierarchy defined for such classes in bytecode, then how does Java establishes this hierarchy?因此我们没有为字节码中的此类类定义任何 class 层次结构,那么 Java 如何建立此层次结构?

To the Java compiler, List<? extends Object>到 Java 编译器, List<? extends Object> List<? extends Object> and List<Object> are different types. List<? extends Object>List<Object>是不同的类型。 This is necessary to enforce type-safety.这是强制类型安全所必需的。 Does it matter that the JVM thinks they are the same? JVM 认为它们相同有关系吗? Not really, because the compiler is a standalone program itself.不是真的,因为编译器本身就是一个独立的程序。 It can stop your code from compiling/allow your code to compile without "consulting" the JVM.它可以阻止您的代码编译/允许您的代码在不“咨询”JVM 的情况下进行编译。 The compiler knows that List< Number> is a subtype of List<? extends Number>编译器知道List< Number>List<? extends Number> List<? extends Number> . List<? extends Number> It knows the type hierarchy, so it can enforce it at compile time.它知道类型层次结构,因此它可以在编译时强制执行它。

What about runtime then?那么运行时呢? As you'd imagine, this type hierarchy of generics cannot be enforced at runtime, because the JVM doesn't know about generics.正如你想象的那样,generics 的这种类型层次结构无法在运行时强制执行,因为 JVM 不知道 generics。 eg this doesn't throw an exception:例如,这不会引发异常:

public class Main {

    public static ArrayList<Object> list;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ArrayList<String> list = new ArrayList<>();
        // here we are doing the equivalent of:
        // Main.list = list;
        // using reflection (hence at runtime)
        Main.class.getField("list").set(null, list);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM