public class Test {
public static void main(String[] args) {
Integer t = 1;
int s = 1;
System.out.println(s != t); // (*)
}
}
Вопрос: что делает компилятор со строкой (*)? Не понимаю, то ли распаковывает t, то ли упаковывает s...
Мудрый человек, пишет что здесь идёт "autoboxing", но с ним мне не связаться и я не знаю почему он так пишет.
Могу предположить только, что раз в сравнении у нас нашёлся Object some_obj, коим является Integer t, то идёт сравнение по ссылкам, и int s автоупаковывается.
Из результатов программы: t==s -- правда. Не знаю почему так... Вроде потому, что есть какой-то метод, который для Integer, String и подобных им приводит объект к некоторому виду, заменяя ссылку на такой же по натуре объект, чтобы == работало. К примеру две "разных" строки, например: "Hello" и "Hello" после вызова этого метода в сравнении == дают true.
Итого: очень хочу увидеть какое-то документальное объяснение происходящего, что к чему приводится, и почему результат строки (*) есть false, что в принципе значит: t и s равны. Но в каком понимании они равны? Ссылок, чисел?... Байт-код мне не помог, там не понять как проходит это сравнение.
Ответ
Происходит распаковывание t (то есть преобразование из Integer в int) с последующим обычным сравнением примитивов (то есть значений типа int).
Чтобы понять почему так происходит обратимся к спецификации Java
Описание оператора == и !=, JLS 15.21.1
If the operands of an equality operator are both of numeric type, or one is of numeric type and the other is convertible (§5.1.8) to numeric type, binary numeric promotion is performed on the operands (§5.6.2).
Если операнды оператора сравнения оба имеют числовой тип, или один из операндов является числовым типом, а второй может быть преобразован в числовой тип, то операнды подвергаются binary numeric promotion
В случае сравнения int и Integer операнд типа int является примитивным типом, а операнд типа Integer может быть преобразован в числовой тип. В принципе не важно, как переводится binary numeric promotion, важно лишь что при этом выполняются действия описанные в соответствующем разделе JLS 5.6.2
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Если один из операндов является ссылочным типом, то происходит распаковывание.
В нашем случае распаковывается Integer и получается int. Далее обычным способом сравниваются два примитива (значения типа int).
Комментариев нет:
Отправить комментарий