Перегрузка операторов в Java

Насколько я знаю в java, я знаю, что на языке Java нет перегрузки оператора. Итак, почему этот код дважды печатает "true"?

    String s1 = "abc";
    String s2 = "abc";
    System.out.println(s1==s2);

    Integer i1 = 1;
    Integer i2 = 1;
    System.out.println(i1==i2);

Ответ 1

== для ссылочных типов сравнивает ссылки; == для примитивных типов сравнивает значения. В случае вашего первого примера, две ссылки на объекты оказываются одинаковыми из-за концепции, известной как пул строк. Следовательно, в данном случае два true. Еще один фрагмент кода, который вы можете попробовать:

String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));

Как вы, должно быть, уже опробовали; он печатает false, а затем true. Причина этого в том, что использование ключевого слова new приводит к созданию полностью новой строки, даже если строковый объект с таким же содержимым уже существует в пуле строк. В этом случае s1 теперь указывает на интернированную строку с содержимым "abc" (или на строку в пуле строк), тогда как s2 теперь указывает на совершенно новый объект строки (опять же с содержимым "abc" ), Следовательно, false в первом заявлении печати. ​​

Во втором заявлении печати мы делаем сравнение содержимого объекта String, а не его ссылки, которое должно печатать true.

Это одна из самых распространенных ошибок, допущенных новичками языка Java; они используют == для логического сравнения, когда это фактически приводит к сравнению сравнения. Прочтите ссылку, размещенную в одном из ответов здесь, для получения более подробной информации о пуле объединения строк. В связанной заметке класс String "переопределяет" метод equals класса Object для обеспечения логического сравнения. Если класс, который вы пишете, не обеспечивает логическую реализацию метода equals, не имеет значения, звоните ли вы equals или используете оператор ==; результат будет таким же, как сравнение ссылок.

Для более глубокого представления о равенстве прочитайте статью Брайана; отличный читать.

Ответ 2

Не совсем верно, что в Java нет перегрузки оператора. Просто не существует какой-либо пользовательской перегрузки оператора. Например, существует некоторая перегрузка оператора с помощью +, которая добавляется как дополнение, так и как String -конкатенация. Это определяется языком и не может быть изменено разработчиком.

Ваш пример, однако, не использует перегрузку оператора в любом месте. == в ссылочных типах всегда делает одно и то же: return true, когда левая и правая стороны относятся к точному тем же объекту.

В этом случае s1 и s2 ссылаются на один и тот же объект и i1 и i2 ссылаются на тот же объект.

  • s1 и s2 ссылаются на один и тот же интернированный String, потому что строковые литералы гарантированно будут интернированы.
  • i1 и i2 ссылаются на один и тот же кешированный Integer, потому что авто-бокс будет повторно использовать фиксированный пул объектов Integer для общих числовых значений.

Ответ 3

Вы не можете перегружать операторы, но это не значит, что он не встроен в JVM. Очевидным примером счетчика является оператор плюс и различное поведение для строк и чисел.

Ответ 6

Ваш код показывает, что он был связан с перегрузкой оператора, но это не так.

Строковый оператор "==", похоже, "перекрыт" с помощью оператора "==" Integer. Как упоминал в предыдущем ответе @Sanjay T. Sharma, в Java существуют "ссылочные" типы и "примитивные" типы, которые обрабатывают разные операторы "==".

Строки в Java являются "ссылочными" типами, а целые являются "примитивными" типами. Если у вас есть указатели и объекты на других языках, вы обнаружите, что в Java строковые переменные действительно являются указателем на объект, а использование оператора "==" ведет себя по-разному.