int.class自动框是否为Class<Integer>

2022-09-04 08:44:26

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

以下代码编译良好,但不应编译,因为 与 的类型不同。这不应该给出编译器错误吗?如果编译器期望在运行时如何解析为?这是编译器让它进入基元的魔法吗?如果编译器放宽对基元的验证,这是否会导致错误,即方法编写者希望该类型是确切的类型,而是被传递 。intIntegerClass<Integer>Class<int>Class<Integer>Class<int>

简而言之,为什么这会在运行时编译并生成or(取决于透视)结果。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>

答案 1

您观察到的是泛型处理基元的方式的直接结果,它不是自动装箱。为了在使用类信息(如泛型或反射)的情况下保持一致,在某些情况下,基元类型在检查其类型时需要返回一些东西。

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

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

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

自 1.1 以来,它们是语言规范的一部分。


答案 2

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

试试这个:

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