Класс String в Java: что это и основные методы - Вопросы

Всего: 7 вопросов

1. 

Что выведет код? Какие ссылочные переменные и объекты String будут созданы до вызова println?

String firstStr = "first ";
String secondStr = firstStr + "second ";
firstStr.concat("third ");
secondStr.concat(firstStr);
firstStr += "fourth ";
System.out.println(firstStr + " " + secondStr);

Вывод: first fourth first second (двойной пробел появляется потому, что firstStr заканчивается пробелом, а в println добавляется ещё один).

Создаются две ссылочные переменные: firstStr и secondStr.

Создаются восемь объектов String: "first ", "second ", "third ", "fourth " (литералы в String Pool) и "first second ", "first third ", "first second first ", "first fourth " (создаются во время выполнения). Результаты двух вызовов concat() никуда не присвоены и теряются: строки неизменяемы, поэтому firstStr и secondStr от этих вызовов не меняются.

2. 

В какой области памяти хранятся строковые литералы?

В String Pool (пуле строк) — специальной области кучи, начиная с Java 7 (до Java 7 пул находился в PermGen). Встретив литерал, JVM сначала ищет такую строку в пуле и, если она там уже есть, возвращает ссылку на существующий объект.

3. 

Сколько объектов создаёт эта строка кода?

String str = "abc";

Одна ссылочная переменная и один объект String: литерал "abc" помещается в String Pool. Если такой литерал в пуле уже есть, новый объект не создаётся, и str получает ссылку на существующий.

4. 

Сколько объектов создаёт эта строка кода?

String worldStr = new String("world");

Два объекта: литерал "world" попадает в String Pool, а new String("world") создаёт ещё один объект String в куче. Переменная worldStr ссылается на объект в куче, поэтому worldStr == "world" вернёт false.

5. 

Какие строки попадают в String Pool автоматически и что делает метод intern()?

Автоматически в пул попадают только строковые литералы и константы времени компиляции (например, final-переменная, склеенная с литералом). Строка, созданная через new или склеенная во время выполнения, — новый объект в куче, поэтому == для неё вернёт false даже при одинаковом тексте. Метод intern() возвращает строку из пула с тем же содержимым и помещает её туда, если её там ещё нет: после этого "Java" == b.intern() вернёт true. Сравнивать текст всё равно нужно через equals().

6. 

Что возвращает метод compareTo() у строк и почему "Java".compareTo("java") возвращает отрицательное число?

Метод сравнивает строки лексикографически, по кодам Unicode, и возвращает число: меньше нуля, если вызывающая строка меньше аргумента, больше нуля — если больше, и 0 — если строки равны. Возвращается разность кодов первых несовпадающих символов, а если одна строка — начало другой, то разность длин ("apple".compareTo("app") = 2). Код 'J' равен 74, а 'j' — 106, поэтому результат -32: заглавные буквы идут раньше строчных, а латиница раньше кириллицы. Для сравнения без учёта регистра есть compareToIgnoreCase(), для сортировки по правилам языка — java.text.Collator.

7. 

Чем метод isEmpty() отличается от isBlank()? Как безопасно проверить, что строка не заполнена?

isEmpty() возвращает true, только если длина строки равна 0. isBlank() (Java 11) возвращает true, если строка пуста или состоит только из пробельных символов: пробелов, табуляций, переводов строк. Поэтому " ".isEmpty() — false, а " ".isBlank() — true. Ни один из методов не проверяет null: вызов на null выбросит NullPointerException, поэтому безопасная проверка выглядит так: s == null || s.isBlank().

Страница 1 из 1