Я учусь на сертификацию 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), это неверно?
-2
lirio oliro 1 Янв 2016 в 21:37

3 ответа

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

Оператор == - это ссылочный оператор равенства. Цитата из JLS:

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

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

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

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

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

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

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    }

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

0
lirio oliro 1 Янв 2016 в 18:56