Подтвердить что ты не робот

Включает ли int.class autobox класс <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>
4b9b3361

Ответ 1

То, что вы наблюдаете, является прямым результатом того, как генерические средства обрабатывают примитивы, а не автоматически бокс. Чтобы быть последовательным в тех случаях, когда будет использоваться информация класса (например, генерики или отражение) примитивные типы в некоторых случаях должны что-то возвращаться при изучении их типа.

При разыменовании anyprimitivetype.class будет возвращено поле TYPE из класса оболочки. В вашем случае это:

 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");
}

Ответ 3

Это потому, что так работают джоки java. Если вы хотите разрешить всем классам, которые наследуются от Лица, вы можете использовать:

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