Подтвердить что ты не робот

Сочетание строк в Java всегда приводит к созданию новых строк в памяти?

У меня длинная строка, которая не соответствует ширине экрана. Напр.

String longString = "This string is very long. It does not fit the width of the screen. So you have to scroll horizontally to read the whole string. This is very inconvenient indeed.";

Чтобы облегчить чтение, я подумал написать это так:

String longString = "This string is very long." + 
                    "It does not fit the width of the screen." +
                    "So you have to scroll horizontally" +
                    "to read the whole string." +
                    "This is very inconvenient indeed.";

Однако я понял, что второй способ использует конкатенацию строк и создаст 5 новых строк в памяти, и это может привести к поражению производительности. Это так? Или компилятор был бы достаточно умен, чтобы понять, что все, что мне нужно, это действительно одна строка? Как я мог избежать этого?

4b9b3361

Ответ 1

Я понял, что второй способ использует конкатенацию строк и создаст 5 новых строк в памяти, и это может привести к поражению производительности.

Нет, не будет. Поскольку это строковые литералы, они будут оцениваться во время компиляции, а будет создана только одна строка. Это определено в Спецификация языка Java 3.10.5:

Длинный строковый литерал всегда может быть разбит на более короткие фрагменты и написан как выражение (возможно, в скобках) с использованием оператора конкатенации строк +
[...]
Более того, строковый литерал всегда ссылается на тот же экземпляр класса String.

  • Строки, вычисленные постоянными выражениями (§15.28), вычисляются во время компиляции, а затем обрабатываются так, как если бы они были литералами.
  • Строки, вычисленные путем конкатенации во время выполнения, создаются и поэтому различны.

Тест:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String other = "This string" + " is " + "very long.";

    System.out.println(longString == other); //prints true
}

Однако ситуация ситуация ниже отличается, потому что она использует переменную - теперь существует конкатенация и создается несколько строк:

public static void main(String[] args) throws Exception {
    String longString = "This string is very long.";
    String is = " is ";
    String other = "This string" + is + "very long.";

    System.out.println(longString == other); //prints false
}

Ответ 2

Сочетание строк в Java всегда приводит к созданию новых строк в памяти?

Нет, это не всегда так.

Если конкатенация является выражением постоянной времени компиляции, то она выполняется компилятором, а полученная строка добавляется в пул констант скомпилированных классов. Во время выполнения значение выражения является интернированным String, которое соответствует записи с постоянным пулом.

Это произойдет в примере вашего вопроса.

Ответ 3

Пожалуйста, проверьте ниже фрагмент на основе ваших входов:

String longString = "This string is very long. It does not fit the width of the screen. So you have to scroll horizontally to read the whole string. This is very inconvenient indeed.";

String longStringOther = "This string is very long. " + 
        "It does not fit the width of the screen. " +
        "So you have to scroll horizontally " +
        "to read the whole string. " +
        "This is very inconvenient indeed.";

System.out.println(" longString.equals(longStringOther) :"+ longString.equals(longStringOther));      
System.out.println(" longString == longStringother : " + (longString == longStringOther ));

Вывод:

longString.equals(longStringOther): true
longString == longStringother: true

1-й случай: обе строки равны (имеют одинаковый контент)

2-й случай: показывает, что после конкатенации есть только одна строка. Так создается только одна строка.