Я изучаю сертификацию OCA 8. Что в Java означает «логическое равенство»?

У меня такой кейс:

String s1 = new String("java");
String s3 = new String("java");
StringBuilder s2 = new StringBuilder("java");
StringBuilder s4 = new StringBuilder("java");

if (s1 == s2)      {    System.out.print("1"); } //error
if (s1.equals(s2)) {    System.out.print("2"); } //false
if (s1.equals(s3)) {    System.out.print("3"); } //true
if (s2.equals(s4)) {    System.out.print("4"); } //false

Деталь:

Метод equals () на объекте String переопределяется для сравнения значения объекта с другим. По этой причине, когда я исключаю строку:

if (s1.equals(s3)) {    System.out.print("3"); } 

У меня результат 3.

Для объекта StringBuilder метод equals () не переопределяется, поэтому он будет сравнивать равенство ссылок на объект. По этой причине, когда я выполняю строку кода:

if (s2.equals(s4)) {    System.out.print("4"); }

У меня результат false.

Мой вопрос:

  • Почему при исключении if (s1 == s2)я получаю ошибку компиляции?
  • Почему, когда я исключаю s1.equals (s2), это ложно?

Ответы (3)

  • Почему при исключении if (s1 == s2) возникает ошибка компиляции?

Оператор == является оператором ссылочного равенства. Цитирование JLS:

Это ошибка времени компиляции, если невозможно преобразовать тип одного из операндов в тип другого посредством преобразования приведения (§5.5).

В вашем случае два операнда имеют тип String и StringBuilder, которые несовместимы: a String не может быть преобразовано в StringBuilder и наоборот.

  • Почему, когда я исключаю s1.equals (s2), это ложь?

String и StringBuilder - это два разных типа. Метод equals () в String проверяет, имеет ли данный аргумент также тип String, что здесь не так, поэтому экземпляр Строка никогда не может быть равна экземпляру StringBuilder.

Я просто обнаружил причину здесь.

1012    public boolean equals(Object anObject) {
1013        if (this == anObject) {
1014            return true;
1015        }
1016        if (anObject instanceof String) {
1017            String anotherString = (String)anObject;
1018            int n = count;
1019            if (n == anotherString.count) {
1020                char v1[] = value;
1021                char v2[] = anotherString.value;
1022                int i = offset;
1023                int j = anotherString.offset;
1024                while (n-- != 0) {
1025                    if (v1[i++] != v2[j++])
1026                        return false;
1027                }
1028                return true;
1029            }
1030        }
1031        return false;
1032    }
• 100001 Строковый объект (и в нем я нашел ответ на свой вопрос о логическом равенстве). Спасибо всем

  1. Почему при исключении if (s1 == s2) возникает ошибка компиляции?
  2. Почему, когда я исключаю s1.equals (s2), это ложь?
  1. Да. Поскольку String не является StringBuilder. Вы получите «несовместимые типы операндов String и StringBuilder» (потому что String не является StringBuilder).
  2. Опять же, потому что String не является StringBuilder. Вы можете использовать s1.equals (s2.toString ()) (что будет true).

2022 WebDevInsider