Согласно String # intern () , intern
метод должен возвращать строку из пула строк, если строка найдена в пуле строк, в противном случае новый объект строки будет добавлен в пул строк и будет возвращена ссылка на эту строку.
Итак, я попробовал это:
String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
if ( s1 == s2 ){
System.out.println("s1 and s2 are same"); // 1.
}
if ( s1 == s3 ){
System.out.println("s1 and s3 are same" ); // 2.
}
Я ожидал, что s1 and s3 are same
это будет напечатано, поскольку s3 интернирован, и s1 and s2 are same
не будет напечатан. Но результат: обе строки напечатаны. Это означает, что по умолчанию строковые константы интернированы. Но если это так, то зачем нам intern
метод? Другими словами, когда мы должны использовать этот метод?
java
string
string-interning
Ракеш Джуял
источник
источник
intern
публичный метод. Разве у нас не должно быть такогоintern
закрытого метода, чтобы никто не мог получить к нему доступ. Или есть ли цель этого метода?Ответы:
Java автоматически интернирует строковые литералы. Это означает, что во многих случаях оператор == работает для строк так же, как и для целочисленных значений или других примитивных значений.
Поскольку интернирование выполняется для строковых литералов автоматически,
intern()
метод должен использоваться в строках, созданных сnew String()
Используя ваш пример:
вернется:
Во всех случаях, кроме
s4
переменной, значение которой было явно создано с помощьюnew
оператора и гдеintern
метод не использовался в ее результате, это единственный неизменный экземпляр, которому возвращается пул строковых констант JVM .Обратитесь к JavaTechniques "Строковое Равенство и Стажировка" для получения дополнительной информации.
источник
String s1 = "Rakesh";
первый OB1,String s4 = new String("Rakesh");
второй OB2, поэтому остальные (s2, s3, s5) ссылаются на тот же объект (OB1), созданный в «пуле строк». Так что я могу сказать, что.intern()
метод, используемый для предотвращения создания нового объекта, если такая же строка доступна вstring pool
If мое предположение неверно, поэтому дайте мне направление.В недавнем проекте, некоторые огромные структуры данных были созданы с данными, которые считывались из базы данных (и, следовательно, не константами / литералами String), но с огромным количеством дублирования. Это было банковское приложение, и повсюду появлялись такие вещи, как названия скромных (возможно, 100 или 200) корпораций. Структуры данных уже были большими, и если бы все эти имена корпусов были уникальными объектами, они бы переполнили память. Вместо этого все структуры данных имели ссылки на одни и те же 100 или 200 объектов String, что позволило сэкономить много места.
Другое небольшое преимущество интернированных строк - это то, что
==
их можно использовать (успешно!) Для сравнения строк, если все вовлеченные строки гарантированно интернированы. Помимо упрощенного синтаксиса, это также повышение производительности. Но, как отмечали другие, выполнение этого таит в себе большой риск появления ошибок программирования, поэтому это следует делать только в качестве отдельной меры крайней меры.Недостатком является то, что интернирование String занимает больше времени, чем простое его выбрасывание в кучу, и что пространство для интернированных строк может быть ограничено в зависимости от реализации Java. Лучше всего это делать, когда вы имеете дело с известным разумным количеством строк со множеством дубликатов.
источник
The downside is that interning a String takes more time than simply throwing it on the heap, and that the space for interned Strings may be limited
даже если вы не используете метод intern для константы String, он будет автоматически интернирован.==
строки, хотя.Я хочу добавить свои 2 цента при использовании
==
с интернированными строками.Первое, что
String.equals
делаетthis==object
.Таким образом, хотя есть небольшой прирост производительности (вы не вызываете метод), с точки зрения сопровождающего использование
==
- это кошмар, потому что некоторые интернированные строки имеют тенденцию становиться не интернированными.Поэтому я предлагаю не полагаться на особый случай
==
интернированных строк, но всегда использовать его так,equals
как задумал Гослинг.РЕДАКТИРОВАТЬ: интернированный становится не интернированным:
В версии 2.0 сопровождающий решил
hasReferenceVal
обнародовать, не вдаваясь в подробности, что он ожидает массив интернированных строк.Теперь у вас есть ошибка, которую может быть очень трудно найти, потому что в большинстве случаев массив содержит литеральные значения, а иногда используется не-литеральная строка. Если бы
equals
использовались вместо того,==
тоhasReferenceVal
все равно продолжали бы работать. Еще раз, прирост производительности незначителен, но затраты на обслуживание высоки.источник
Строковые литералы и константы интернированы по умолчанию. То есть
"foo" == "foo"
(объявлено строковыми литералами), ноnew String("foo") != new String("foo")
.источник
intern
,String literals and constants are interned by default
правильно.new String("foo")
-> Здесь один строковый литерал "foo" создается в пуле строк, а другой - в куче, поэтому создается всего 2 объекта.Выучите Java String Intern - раз и навсегда
Строки в Java являются неизменными объектами по своему дизайну. Следовательно, два строковых объекта даже с одинаковым значением будут разными объектами по умолчанию. Однако, если мы хотим сэкономить память, мы можем указать на использование той же памяти с помощью концепции, называемой string intern.
Приведенные ниже правила помогут вам понять концепцию в четких терминах:
Пример:
Примечание: мотивационные случаи для строкового интерна здесь не обсуждаются. Тем не менее, сохранение памяти, безусловно, будет одной из основных задач.
источник
Вы должны разобрать два периода времени, которые являются временем компиляции и временем выполнения. Например:
с одной стороны, в примере 1 мы находим, что все результаты возвращают true, потому что во время компиляции jvm поместит «test» в пул литеральных строк, если jvm find «test» существует, тогда он будет использовать существующий, в примере 1 все строки «test» указывают на один и тот же адрес памяти, поэтому в примере 1 будет возвращаться true. с другой стороны, в примере 2 метод substring () выполняется во время выполнения, в случае "test" == "! test" .substring (1), пул создаст два строковых объекта " test "и"! test ", поэтому они являются разными ссылочными объектами, поэтому в этом случае будет возвращено значение false, в случае" test "=="! test ".substring (1) .intern (), метод intern ( ) поместит "! test" .substring (1) "в пул литеральных строк,
источник
http://en.wikipedia.org/wiki/String_interning
Интернирование строк - это метод хранения только одной копии каждого отдельного строкового значения, которое должно быть неизменным. Стажировка строк делает некоторые задачи обработки строк более экономичными по времени или пространству за счет того, что при создании или интернировании строки требуется больше времени. Отдельные значения хранятся в строковом внутреннем пуле.
источник
Interned Strings избегают дублирования строк. Interning экономит оперативную память за счет увеличения процессорного времени для обнаружения и замены дублирующихся строк. Существует только одна копия каждой строки, которая была интернирована, независимо от того, сколько ссылок указывают на нее. Поскольку строки являются неизменяемыми, если два разных метода случайно используют одну и ту же строку, они могут совместно использовать копию одной строки. Процесс преобразования дублированных строк в разделяемые называется interning.String.intern (), дает вам адрес канонического мастера String. Вы можете сравнить интернированные строки с простым == (который сравнивает указатели) вместо равнокоторый сравнивает символы строки по одному. Поскольку строки являются неизменяемыми, внутренний процесс может дополнительно экономить пространство, например, не создавая отдельный литерал String для «pot», если он существует в качестве подстроки некоторого другого литерала, такого как «бегемот».
Чтобы увидеть больше http://mindprod.com/jgloss/interned.html
источник
ВЫВОД
источник
Когда две строки создаются независимо, это
intern()
позволяет сравнивать их, а также помогает создавать ссылку в пуле строк, если ссылка не существовала ранее.Когда вы используете
String s = new String(hi)
, java создает новый экземпляр строки, но когда вы используетеString s = "hi"
, java проверяет, есть ли экземпляр кода «hi» в коде или нет, и если он существует, он просто возвращает ссылку.Поскольку сравнение строк основано на ссылках,
intern()
помогает вам создать ссылку и позволяет сравнивать содержимое строк.Когда вы используете
intern()
в коде, он очищает пространство, используемое строкой, ссылающейся на тот же объект, и просто возвращает ссылку на уже существующий тот же объект в памяти.Но в случае p5, когда вы используете:
Только содержимое p3 копируется и p5 создается заново. Так что это не интернировано .
Таким образом, результат будет:
источник
источник
Метод string intern () используется для создания точной копии строкового объекта кучи в пуле строковых констант. Строковые объекты в пуле строковых констант автоматически интернируются, а строковые объекты в куче - нет. Основное использование создания интернов - это сохранение места в памяти и более быстрое сравнение строковых объектов.
Источник: Что такое строка интерна в Java?
источник
Как вы сказали, этот
intern()
метод строки сначала найдет из пула String, если он найдет, то он вернет объект, который указывает на это, или добавит новую строку в пул.s1
Иs2
два объекта , указывающие на Струнный пул «Привет», и с помощью"Hello".intern()
обнаружат , чтоs1
иs2
. Так что"s1 == s3"
возвращает истину, как и вs3.intern()
.источник
Используя ссылку на объект кучи, если мы хотим получить соответствующую ссылку на объект пула строковой константы , мы должны перейти к intern ()
Живописный вид
Шаг 1: Объект с данными 'Rakesh' создается в пуле кучи и строковой константы. Также s1 всегда указывает на объект кучи.
Шаг 2: Используя ссылку на объект кучи s1, мы пытаемся получить соответствующий объект пула строковой константы referenc s2, используя intern ()
Шаг 3: Преднамеренное создание объекта с данными 'Rakesh' в пуле строковых констант, на который ссылается имя s3
Поскольку оператор "==" предназначен для сравнения ссылок.
Получение ложной для s1 == s2
Становится правдой для s2 == s3
Надеюсь, это поможет!
источник