← Назад к вопросам

Как работает == в Java?

1.6 Junior🔥 271 комментариев
#JVM и память#Kotlin основы

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Работа оператора == в Java

В Java оператор == является оператором сравнения, но его поведение кардинально различается в зависимости от типа операндов: примитивных типов или ссылочных типов.

Сравнение примитивных типов

Для примитивных типов (int, char, double, boolean и т.д.) оператор == сравнивает фактические значения переменных:

int a = 5;
int b = 5;
int c = 10;

System.out.println(a == b); // true, значения равны
System.out.println(a == c); // false, значения различны

double x = 3.14;
double y = 3.14;
System.out.println(x == y); // true (с учетом точности double)

char ch1 = 'A';
char ch2 = 'A';
System.out.println(ch1 == ch2); // true, символы одинаковы

Сравнение ссылочных типов

Для объектов и массивов (все, что не является примитивным типом) оператор == сравнивает ссылки (адреса в памяти), а не содержимое объектов:

String s1 = new String("Hello");
String s2 = new String("Hello");
String s3 = s1;

System.out.println(s1 == s2); // false! Разные объекты в памяти
System.out.println(s1 == s3); // true, обе переменные ссылаются на один объект

int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
int[] arr3 = arr1;

System.out.println(arr1 == arr2); // false, разные массивы
System.out.println(arr1 == arr3); // true, одна ссылка

Особенности String и пула строк

Для класса String ситуация осложняется наличием пула строк (String Pool):

String a = "Hello"; // Литерал попадает в String Pool
String b = "Hello"; // Берется из String Pool
String c = new String("Hello"); // Создается новый объект в куче

System.out.println(a == b); // true! Одна ссылка на объект в пуле
System.out.println(a == c); // false, разные объекты
System.out.println(a.equals(c)); // true, содержимое одинаковое

Метод equals() для сравнения объектов

Для корректного сравнения содержимого объектов необходимо использовать метод equals():

String s1 = new String("Test");
String s2 = new String("Test");

System.out.println(s1 == s2); // false - сравниваются ссылки
System.out.println(s1.equals(s2)); // true - сравнивается содержимое

// Для собственных классов нужно переопределять equals()
class Person {
    private String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return Objects.equals(name, person.name);
    }
}

Автоупаковка и сравнение

При сравнении с участием автоупаковки могут возникнуть неочевидные ситуации:

Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;

System.out.println(i1 == i2); // true (значения кэшируются для -128..127)
System.out.println(i3 == i4); // false (разные объекты)

Практические рекомендации

  1. Для примитивов всегда используйте == для сравнения значений
  2. Для объектов используйте == только когда нужно проверить, являются ли две ссылки одним и тем же объектом
  3. Для сравнения содержимого объектов всегда используйте equals() (предварительно убедившись, что он правильно переопределен)
  4. Для массивов используйте Arrays.equals() для сравнения содержимого
  5. Особое внимание к сравнениям с null: obj == null — безопасная проверка на null

Ключевые выводы

  • == сравнивает значения для примитивов и ссылки для объектов
  • Не путайте == с equals() — это разные операции с разной семантикой
  • Понимание различий критически важно для избежания логических ошибок
  • Для строк литералы могут быть равны через == благодаря String Pool, но это исключение, а не правило

Правильное использование оператора == — фундаментальный навык Java-разработчика, напрямую влияющий на корректность работы программы и предотвращающий множество трудноуловимых ошибок.