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

Вопрос Java об автобоксинге и равенстве/идентичности объекта

public class Main { 
    /** 
      * @param args the command line arguments */ 
    public static void main(String[] args) { 
        // TODO code application logic here
        int a1 = 1000, a2 = 1000; 
        System.out.println(a1==a2);//=>true 
        Integer b1 = 1000, b2 = 1000;
        System.out.println(b1 == b2);//=>false 
        Integer c1 = 100, c2 = 100; 
        System.out.println(c1 == c2);//=>true 
    }

}

Почему b1 == b2 false и c1 == c2 true?

4b9b3361

Ответ 1

Прочитайте этот.

Java использует пул для Integer в диапазоне от -128 до 127.

Это означает, что если вы создаете Integer с Integer i = 42; и его значение находится между -128 и 128, no создается новый объект, но возвращается соответствующий из пула. Вот почему c1 действительно идентичен c2.

(Я полагаю, вы знаете, что == сравнивает ссылки, а не значения, когда применяется к объектам).

Ответ 2

Правильные ответы уже даны. Но просто чтобы добавить мои два цента:

Integer b1 = 1000, b2 = 1000;

Это ужасный код. Объекты должны быть инициализированы как объекты через конструкторы или методы factory. Например.

 // let java decide if a new object must be created or one is taken from the pool
Integer b1 = Integer.valueOf(1000);

или

 // always use a new object
 Integer b2 = new Integer(1000);

Этот код

Integer b1 = 1000, b2 = 1000;

с другой стороны, означает, что Integer был примитивным, а это не так. Фактически, что вы видите, это ярлык для

Integer b1 = Integer.valueOf(1000), b2 = Integer.valueOf(1000);

и Integer объединяет только объекты с -127 до 127, поэтому в этом случае будет создано два новых объекта. Поэтому, хотя 1000 = 1000, b1!= B2. Это главная причина, по которой я ненавижу авто-бокс.

Ответ 3

Здесь вы можете найти ответ:

Самая странная функция языка в 6-м ответе.

Изменить: извините, но не полностью ответ. Дело в том, что == сравнивает ссылки, а не значения, когда вы используете его с Integer. Но с int "==" означает equals.

Ответ 4

Потому что Integer для нескольких низких чисел, таких как перечисление, так что всегда есть один и тот же экземпляр. Но более высокие числа создают новые экземпляры Integer, а оператор == сравнивает их ссылки

Ответ 5

  public static Integer valueOf(int i) {
      final int offset = 128;
      if (i >= -128 && i <= 127) { // must cache
          return IntegerCache.cache[i + offset];
      }
       return new Integer(i);
    }

Из-за этого вы верны в одном случае, а false в другом!

Ответ 6

Ответ, который вы хотите, здесь

Ответ 7

Если autounbing работал также при выполнении проверки равенства с помощью оператора '==', вы могли бы написать:

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( notNullSafeLong1 == notNullSafeLong2) {
      do suff

Для этого потребуется реализовать переопределение для ==, так что null == someLong является ложным, а специальный регистр Null == Null - true. Вместо этого мы должны использовать equal() и test для null

    Long notNullSafeLong1 = new Long(11L)
    Long notNullSafeLong2 = new Long(22L)
    if ( (notNullSafeLong1 == null && notNullSafeLong2 == null) || 
      (notNullSafeLong1 != null && notNullSafeLong2 != null & 
        notNullSafeLong1.equals(notNullSafeLong2)) {
      do suff    

Это немного более подробный, чем первый пример - если autounboxing работал для оператора '=='.