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

Сравнение примитива с объектом-оболочкой с необработанным поведением

У меня есть фрагмент кода, который мне нужно понять:

public static void main(String[] args) {
    Character c = new Character('a');
    Character cy = new Character('a');
    char cx = 'a';

    System.out.println(c == cx);
    System.out.println(cx == cy);
    System.out.println(c == cy);
}

Вывод:

true
true
false

Я не могу понять, почему только третий оператор терпит неудачу.

EDIT: этот вопрос отличается от вопроса .equals vs == как это о сравнении примитивов и объектов.

4b9b3361

Ответ 1

c и cy относятся к разным экземплярам класса Character (каждый раз, когда вы вызываете конструктор, вы создаете новый экземпляр), поэтому сравнение этих ссылок возвращает false.

С другой стороны, когда вы сравниваете любой из них с примитивным cx, они распаковываются в char, а сравнение char возвращает true.

Если бы вы использовали Character.valueOf('a') вместо new Character('a'), вы бы получили тот же экземпляр в обоих вызовах, и ссылочное сравнение вернуло бы true (так как valueOf возвращает экземпляр кешированного Character, если аргумент <= 127).

Ответ 2

 System.out.println(c == cx);
 System.out.println(cx == cy);

Так как один является примитивным, а другой является его классом-оболочкой, unboxing происходит, и выполняется примитивное сравнение (==).

В то время как:

 System.out.println(c == cy);

- сравнение объектов. Различные экземпляры сравниваются, поэтому == не будет работать в этом случае.

Ответ 3

класс Charcter не является одиночным, поэтому всегда создается новый объект при вызове конструктора, а новые объекты ссылаются на соответствующие ссылки. (c == cy) дает вам false

Ответ 4

очевидно, почему последнее сравнение дает false: оба Character явно инициализируются с помощью new, поэтому являются разными объектами

почему первые два сравнения дают true, однако, только отчасти ясны: значение char определенно используется для извлечения предварительно сохраненного экземпляра Character, но я не знаю, определенные объекты Character сопоставляются с этим предварительно сохраненным экземпляром

Я бы ожидал, однако, он работает как "==" - сравнение для объектов String: если во время компиляции один из сравниваемых экземпляров является предварительно сохраненным Character, тогда компилятор вставляет вызов equals() заменяя "==" - сравнение