Струнные старинные головоломки
Возможный дубликат:
intern() ведет себя по-разному в Java 6 и Java 7
На этом blog Я нашел интересные головоломки String:
--- Цитата ---
String te = "te", st = "st";
//"test".length();
String username = te + st;
username.intern();
System.out.println("String object the same is: "
+ (username == "test"));
печатает под обновлением версии 7 7.
String object the same is: true
но раскомментируйте "test".length(); line или запустить с помощью Java 6 и печатает
String object the same is: false
--- EoQ ---
Будучи честным, я не понимаю, почему результаты разные. Не могли бы вы объяснить мне, в чем причина такого поведения?
Ответы
Ответ 1
Вам нужно присвоить интернированную строку имени пользователя:
String username = te + st;
username = username.intern();
В этом случае оба кода выдадут true
.
Вот еще один интересный пример:
final String te = "te", st = "st";
"test".length();
String username = (te + st);
System.out.println("String object the same is: " + (username == "test"));
также выводит истину, так как те и st отмечены как окончательные. Таким образом, имя пользователя становится константой времени компиляции и автоматически интернируется.
ИЗМЕНИТЬ
Как отметили несколько человек, ваш код печатает false с Java 6, даже если строка "test".length
закомментирована.
Это связано с одним из изменений, внесенных в Java 7:
в JDK 7 интернированные строки больше не выделяются в постоянном поколении кучи Java, а вместо этого выделяются в основной части кучи Java (так называемые молодые и старые поколения) вместе с другими созданными объектами с помощью приложения.
Одним из следствий является то, что код, который вы опубликовали, имеет разные выходы в Java 6 и 7 (см. пример внизу отчета об ошибке).
Ответ 2
Пожалуйста, проверьте ответ Указывает ли String.intern() ссылку на исходную строку
Изменена не строка, а объект, который используется для "теста", который изменяется.
Итак, в вашем случае, если "test"
определено первым, что означает, что если вы делаете сначала "test".length();
, то "test"
находится в пуле строк, поэтому первый результат false
.
Теперь if you comment this line
, после вызова username.intern();
"test" добавляется в пул строк теперь следующий "test"
, который вы используете для сравнения, получает тот же объект, который был помещен методом username.intern();
. Следовательно, true
так
Commented //"test".length(); -> True
Un Commented "test".length(); --> False