Почему значения в целочисленных значениях и .getClass () == - равны, а не только .equals () - равны? - PullRequest
4 голосов
/ 19 сентября 2011

Возможно, я слишком долго работал над Java, не понимая некоторых его основ.
Я понимаю, что == - для равенства ссылок на объекты, а .equals() - для равенства значений объектов.

  1. Сравнение Integers:

    Integer x = 1, y = 1;  
    System.out.println(x == y); // true
    

    Почему?Поскольку используется равенство ссылок на объекты, оно должно быть ложным, поскольку оба они являются разными объектами.

  2. Сравнение getClass() возвращаемых значений:

    String s1 = "a", s2 = "b";  
    System.out.println(s1.getClass() == s2.getClass()); // true 
    

    Почему?Снова, как указано выше, используется ссылка на объект.Обе команды, использующие getClass, будут возвращать отдельные объекты Class.

Я что-то упустил или мой разум слишком устал от написания кода на Java?

Ответы [ 4 ]

12 голосов
/ 19 сентября 2011

Целочисленные объекты

Integer x = 1, y = 1;
System.out.println(x==y); // true, why?

Это происходит потому, что для значений в диапазоне byte (от -128 до +127) java использует кэшированные объекты Integer, хранящиеся во внутреннем классе Integer , IntegerCache . Каждый раз, когда объект Integer создается со значением в диапазоне от -128 до +127, возвращается один и тот же объект (вместо создания new объекта).

И наоборот, для значений вне диапазона byte сравнение составляет false:

Integer x = 999, y = 999;
System.out.println(x==y); // false

Объекты класса

String s1 = "a", s2 = "b";
System.out.println(s1.getClass() == s2.getClass()); // true. Why?

Это верно, потому что класс обоих объектов равен String, и существует только одна копия каждого объекта класса на JVM (это похоже на синглтон). объект класса , возвращаемый из getClass() каждой строки, равен того же объекта класса (String.class).

0 голосов
/ 19 сентября 2011

Ваше понимание == и equals() верно. В первом случае это так из-за кеширования. Во втором случае класс объекта всегда один и тот же, он не зависит от экземпляра. Если бы это было так, это было бы огромной тратой памяти.

0 голосов
/ 19 сентября 2011

Если вы еще не знаете, это связано с концепцией автобоксирования / распаковки. Таким образом, когда вы сравниваете Integer объекты, вы можете себе представить, что компилятор автоматически добавляет intValue() при их сравнении - так что это, по сути, становится сравнением примитивного значения, а не равенством объектов.

Что касается строки, то это потому, что она сравнивает классы / типы, которые всегда являются единичными (и, следовательно, одинаковыми) в JVM.

0 голосов
/ 19 сентября 2011

а это хороший вопрос. Поскольку Integer s являются неизменяемыми, реализация Java не гарантирует, что вы получите уникальный объект для каждого целого числа. Java использует пул Integer объектов для небольших значений от -128 до +127, поэтому a и b оба ссылаются на один и тот же базовый 1 объект.

Что касается b, обе строки являются экземплярами одного класса String. getClass() возвращает один и тот же Class объект для каждого.

...