Ниже приведен комментарий Javadoc для метода String.intern ():
* Возвращает каноническое представление для строкового объекта.
Пул строк, изначально пустой , поддерживается в частном порядке классом String.
При вызове метода intern, если пул уже содержит строку, равную этому объекту String, как определено методом equals (Object), возвращается строка из пула. В противном случае этот объект String добавляется в пул и возвращается ссылка на этот объект String.
Отсюда следует, что для любых двух строк s и t s.intern () == t.intern () имеет значение true, если и только если s.equals (t) имеет значение true.
Все литеральные строки и строковые константные выражения интернированы. Строковые литералы определены в разделе 3.10.5 Спецификации языка Java ™. ”
Но я думаю, что что-то изменило jdk-8u102 вперед.
Проверьте ниже пример:
public class Test1 {
public static void main(String[] args) {
String s1 = new String(new char[]{'J', 'a', 'v', 'a'});
String s2 = s1.intern();
System.out.println(s1 == s2);
}
}
Если вы запустите вышеуказанную программу в JDK 7u80 (последняя стабильная версия JDK 7) и JDK 8 до 8u101, то вы получите:
true
Но если вы запустите вышеуказанную программу в JDK 8u102 и далее в JDK 9 и JDK 10, то вы получите:
false
Почему метод intern () начал работать по-разному в JDK 8u102 и далее?
Я проверил примечания к выпуску и комментарии Javadoc, но не смог найти ничего об изменениях, связанных с методом intern () в JDK 8u102.
Я проверил блоги и другие сайты, но не повезло.
Но когда я попытался с какой-то другой строкой, в выводе не было никаких изменений:
public class Test2 {
public static void main(String[] args) {
String s3 = new String(new char[]{'U', 'd', 'a', 'y', 'a', 'n'});
String s4 = s3.intern();
System.out.println(s3 == s4);
}
}
Приведенная выше программа всегда печатает true в JDK 7, JDK 8, JDK 9 и JDK 10.
Такое поведение возможно только в том случае, если перед загрузкой класса Test1 таблица «Строка пула» указывает «Java».
s1 ссылается на объект String «Java» в HEAP, а s1.intern () возвращает ссылку на объект String Pool (поскольку «Java» уже упоминается в String Pool).
Вот почему s1 == s2 возвращает false.
Но когда загружен класс Test2, «Udayan» НЕ указывается в таблице пула строк.
s3 ссылается на объект String «Udayan» в HEAP, а s3.intern () добавляет объект String, на который ссылается s3, в String Pool и возвращает ту же ссылку. Это означает, что s3 и s4 относятся к одному и тому же объекту.
Вот почему s3 == s4 возвращает true.
Если мои наблюдения верны, то это означает, что пул строк НЕ пуст изначально.
Пул строк изначально содержит «Java», «java», «Oracle» и другие объекты String.
Может кто-нибудь подтвердить это?