int.class 自动装箱到 Class<Integer>

Does int.class autobox to Class<Integer>

我确定我的问题没有意义,但这是因为我不知道我看到了什么或如何描述它...

以下代码可以正常编译,但不应该,因为 intInteger 不是同一类型。这不应该给出编译器错误吗?如果编译器期望 Class<Integer> 的类型,它在运行时如何解析为 Class<int>?这是编译器让它继续使用原语的魔法吗?如果编译器放宽对基元的验证,这不会导致方法编写者期望类型为精确类型 Class<Integer> 而交付的错误 Class<int>.

简而言之,为什么这会在运行时编译并产生 correctwrong(取决于视角)结果。

public static void main(String[] args) {

    printClass("int     ", int.class);
    printClass("Integer ", Integer.class);
    System.out.printf("AreEqual", int.class == Integer.class);
}

private static void printClass(String text, final Class<Integer> klazz) {
    System.out.printf("%s: %s%s", text, klazz, "\n");
}

输出:

int     : int
Integer : class java.lang.Integer
AreEqual: false

对于对照组,这段代码 NOT COMPILE 正如我所期望的那样

public static void main(String[] args) {

    printClass("Person  ", Person.class);
    printClass("Employee", Employee.class);
    System.out.printf("AreEqual: %s", Person.class == Employee.class);
}

private static void printClass(String text, final Class<Person> klazz) {
    System.out.printf("%s: %s%s", text, klazz, "\n");
}


public class Employee extends Person {
}
public class Person {
}

错误:

Error:(8, 40) java: incompatible types: java.lang.Class<com.company.Employee> cannot be converted to java.lang.Class<com.company.Person>

因为自 Java 5 个原始类型以来存在隐式自动装箱。 对于其他类型,您需要使用其他语法来实现您的目标:搜索 Generics。

试试这个:

private static void printClass(String text, final Class<? extends Person> klazz) {
    System.out.printf("%s: %s%s", text, klazz, "\n");
}

那是因为这是 java 泛型的工作方式。如果你想允许所有继承自 Person 的 类,你可以使用:

private static void printClass(String text, final Class<? extends Person> klazz) {

您观察到的是泛型处理基元的方式的直接结果,它不是自动装箱。在 class-信息将被使用(如泛型或反射),在某些情况下原始类型在检查它们的类型时需要 return 和一些东西。

当取消引用 anyprimitivetype.class 时,封闭包装器 class 中的 TYPE 字段将被 returned。在你的情况下是:

 int.class -> public static final Class<Integer> TYPE

您可以在此处找到所有基本类型加上 void 的完整列表: primitives

从 1.1 开始它们就是语言规范的一部分。