Почему сравнение строк отличается?

176
22 июня 2022, 18:20

В первом методе выводится значение false, во втором - true. Мои мысли: в test1(), когда создается d - уже в String Pool существует c. Но получается d дублируется. Поведение test2() мне понятно. Можете объяснить логику создания c и d в test1()?

public class Main
{
    public static void main(String[] args) {
        System.out.println("Hello World");
        test1();
        test2();
    }
    
    public static void test1() {
        String a = "a";
        String b = "b";
        // String c = a + b;
        String c = a.concat(b);
        String d = "ab";
        System.out.println(c == d);
    }
    public static void test2() {
        String a = "ab";
        String b = "a" + "b";
        System.out.println(a == b);   
    }
}

байт-код:

public static void test1();
    Code:
       0: ldc           #7                  // String a
       2: astore_0
       3: ldc           #8                  // String b
       5: astore_1
       6: aload_0
       7: aload_1
       8: invokevirtual #9                  // Method java/lang/String.concat:(Ljava/lang/String;)Ljava/lang/String;
      11: astore_2
      12: ldc           #10                 // String ab
      14: astore_3
      15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: aload_2
      19: aload_3
      20: if_acmpne     27
      23: iconst_1
      24: goto          28
      27: iconst_0
      28: invokevirtual #11                 // Method java/io/PrintStream.println:(Z)V
      31: return
  public static void test2();
    Code:
       0: ldc           #10                 // String ab
       2: astore_0
       3: ldc           #10                 // String ab
       5: astore_1
       6: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       9: aload_0
      10: aload_1
      11: if_acmpne     18
      14: iconst_1
      15: goto          19
      18: iconst_0
      19: invokevirtual #11                 // Method java/io/PrintStream.println:(Z)V
      22: return
Answer 1

Помещать или нет строку в пул решает компилятор. Во втором случае он решил что обе строки можно поместить в пул. В первом тесте c в пул не попадает. Это объясняет разницу в тестах.

Другой вопрос как с этим жить программисту?

Вот так: не использовать == на строках если вы не уверены что обе помещены в пул. Используйте .intern() для помещения строк в пул.

READ ALSO
Объясните, пожалуйста, как происходит вывод двумерного массива на Java?

Объясните, пожалуйста, как происходит вывод двумерного массива на Java?

Пытаюсь понять, почему во вложенном цикле for (int j = 0; j < nums[i]length; j++) j < nums[i]

226
Проблема с циклом foreach для коллекции

Проблема с циклом foreach для коллекции

Есть некоторая коллекция bookcase:

179
Активация профиля application.properties в зависимости от среды запуска

Активация профиля application.properties в зависимости от среды запуска

Приложение разрабатывается и тестируется на хосте под Windows и должно запускаться в контейнере DockerСоответственно в Docker-compose запускается отдельный...

241
Cравнение строк

Cравнение строк

C клавиатуры вводится "Hello", по почему-то выдает false,хотя вроде бы строки равны

268