Струнные старинные головоломки

Возможный дубликат:
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