Вывод — true, false, false. В объяснении условия есть ошибка: String.valueOf(Object) не обязан создавать строку; здесь он вызывает toString у уже созданного String и возвращает тот же объект.
Сравнение строк в Java: интернирование, синхронизация и результаты операторов ==
Вывод — true, false, false. В объяснении условия есть ошибка: String.valueOf(Object) не обязан создавать строку; здесь он вызывает toString у уже созданного String и возвращает тот же объект.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Разберите, какой вывод получит программа и почему. Объясните различия между переменными a, a1, a2 и a3, где происходит интернирование строк, и можно ли использовать строки в качестве монитора для синхронизации. Какие потенциальные проблемы могут возникнуть при таком подходе?
public class StringQuiz {
public static void main(String[] args) {
String a = "aaaa";
String a1 = "aaaa";
String a2 = new String("aaaa");
String a3 = String.valueOf(new String("aaaa"));
System.out.println(a == a1); // ?
System.out.println(a == a2); // ?
System.out.println(a == a3); // ?
}
}
Что нужно объяснить:
- Почему
a == a1возвращаетtrue(обе ссылки указывают на одну интернированную строку). - Почему
a == a2возвращаетfalse(объект создан операторомnew, находится в heap, не интернирован). - Почему
a == a3тожеfalse–String.valueOfсоздаёт новую строку, а не использует уже интернированную константу. - Где именно в коде происходит интернирование (при загрузке литерала
"aaaa"). - Возможна ли синхронизация на объекте
String(synchronized (a) { … }). Обсудите, что это технически допустимо, но может привести к непредсказуемым конфликтам, так как одинаковые литералы в разных частях программы могут ссылаться на один и тот же объект, тем самым создавая скрытую блокировку между независимыми участками кода. - Какие альтернативы безопаснее (использовать отдельный объект‑мьютекс).
Ответ
Вывод — true, false, false. В объяснении условия есть ошибка: String.valueOf(Object) не обязан создавать строку; здесь он вызывает toString у уже созданного String и возвращает тот же объект.
A и a1 получают интернированный литерал. A2 создаётся через new. Для a3 выражение new String("aaaa") тоже создаёт отдельный объект, а String.toString возвращает себя; автоматического intern у valueOf нет. Синхронизация на String технически возможна, но литералы могут разделяться независимым кодом, создавая скрытую общую блокировку. Предпочтителен private final Object lock = new Object(), который не публикуется наружу.