http://kohlerm.blogspot.co.uk/2009/01/is-javalangstringintern-really-evil.html
утверждает, что String.equals()
использует "=="
для сравнения String
объектов раньше, в соответствии с
http://www.codeinstructions.com/2009/01/busting-javalangstringintern-myths.html
он сравнивает длины строк, а затем содержимое.
(Между прочим, строки кода продукта в каталоге продаж должны быть одинаковой длины - BIC0417 - защитный шлем велосипедиста, TIG0003 - живой тигр взрослого мужчины - вам, вероятно, понадобятся все виды лицензий, чтобы заказать одну из них. И может быть, вам лучше заказать защитный шлем в то же время.)
Таким образом, звучит так, как будто вы получаете выгоду от замены строк на их intern()
версию, но вы получаете безопасность - и удобочитаемость, а также соответствие стандартам - без использования «==» для equals()
вашего программирования. И большая часть того, что я собираюсь сказать, зависит от того, является ли это правдой, если это правда.
Но String.equals()
проверяет ли вы, что передали ему строку, а не какой-либо другой объект, перед использованием "=="
? Я не квалифицирован, чтобы сказать, но я не думаю, потому что в подавляющем большинстве таких equals()
операций будет String to String, так что тест почти всегда проходит. Действительно, приоритизация «==» внутри String.equals()
подразумевает уверенность в том, что вы часто сравниваете строку с одним и тем же реальным объектом.
Надеюсь, никто не удивится, что следующие строки выдают результат «false»:
Integer i = 1;
System.out.println("1".equals(i));
Но если вы измените i
к i.toString()
во второй строке, конечно , это true
.
Места, где вы можете надеяться на выгоду от стажировки, включают Set
и Map
, очевидно. Я надеюсь, что в интернированных строках кэшируются их хэш-коды ... Я думаю, что это будет требованием. И я надеюсь, что я не просто выдал идею, которая могла бы заработать мне миллион долларов. :-)
Что касается памяти, также очевидно, что это важный предел, если у вас большой объем Strings или если вы хотите, чтобы объем памяти, используемой вашим программным кодом, был очень маленьким. Если ваш объем -distinct-Strings очень велик, возможно, пришло время рассмотреть возможность использования выделенного программного кода базы данных для управления ими и отдельного сервера базы данных. Аналогично, если вы можете улучшить небольшую программу (которая должна запускаться в 10000 экземпляров одновременно), если она вообще не хранит свои строки.
Создавать новую строку, а затем сразу же отбрасывать ее для intern()
замены, кажется бесполезной , но не существует четкой альтернативы, кроме как сохранить дублирующую строку. Таким образом, на самом деле стоимость выполнения заключается в поиске вашей строки в пуле интернов, а затем в том, чтобы сборщик мусора мог удалить оригинал. И если это строковый литерал, то он все равно интернируется.
Мне интересно, intern()
может ли злонамеренный программный код использоваться для обнаружения того, что некоторые строки и их ссылки на объекты уже существуют в intern()
пуле и, следовательно, существуют в другом месте сеанса Java, когда это не должно быть известно. Но это возможно только тогда, когда программный код уже используется доверительно, я думаю. Тем не менее, стоит подумать о сторонних библиотеках, которые вы включаете в свою программу для хранения и запоминания своих ПИН-кодов банкоматов!