int.class 自动装箱到 Class<Integer>
Does int.class autobox to Class<Integer>
我确定我的问题没有意义,但这是因为我不知道我看到了什么或如何描述它...
以下代码可以正常编译,但不应该,因为 int
与 Integer
不是同一类型。这不应该给出编译器错误吗?如果编译器期望 Class<Integer>
的类型,它在运行时如何解析为 Class<int>
?这是编译器让它继续使用原语的魔法吗?如果编译器放宽对基元的验证,这不会导致方法编写者期望类型为精确类型 Class<Integer>
而交付的错误 Class<int>
.
简而言之,为什么这会在运行时编译并产生 correct
或 wrong
(取决于视角)结果。
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 开始它们就是语言规范的一部分。
我确定我的问题没有意义,但这是因为我不知道我看到了什么或如何描述它...
以下代码可以正常编译,但不应该,因为 int
与 Integer
不是同一类型。这不应该给出编译器错误吗?如果编译器期望 Class<Integer>
的类型,它在运行时如何解析为 Class<int>
?这是编译器让它继续使用原语的魔法吗?如果编译器放宽对基元的验证,这不会导致方法编写者期望类型为精确类型 Class<Integer>
而交付的错误 Class<int>
.
简而言之,为什么这会在运行时编译并产生 correct
或 wrong
(取决于视角)结果。
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 开始它们就是语言规范的一部分。