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()
передбачає впевненість, що ви часто порівнюєте String з тим самим фактичним об'єктом.
Я сподіваюся, що ніхто не здивований, що наступні рядки дають результат "помилкового":
Integer i = 1;
System.out.println("1".equals(i));
Але якщо ви зміните i
до i.toString()
у другому рядку, звичайно , це true
.
Місця, де ви можете сподіватися на користь від стажування, включають Set
і Map
, очевидно. Я сподіваюсь, що в інтернованих рядках є свої хеш-коди ... Я думаю, це було б вимогою. І я сподіваюся, що я не просто дав ідею, яка могла б заробити мені мільйон доларів. :-)
Що стосується пам'яті, то також очевидно, що це важлива межа, якщо обсяг Strings великий, або якщо ви хочете, щоб пам'ять, використовувана вашим програмним кодом, була дуже маленькою. Якщо ваш об'єм -distinct- Strings дуже великий, можливо, настав час розглянути можливість використання спеціального коду програми для управління ними та окремого сервера баз даних. Так само, якщо ви можете вдосконалити невелику програму (яку потрібно запускати 10000 екземплярів одночасно), не дозволяючи їй взагалі зберігати свої Strings.
Створювати нову струну, а потім відкидати її відразу, замість неї intern()
марно, але немає чіткої альтернативи, окрім збереження дубліката String. Тож дійсно вартість виконання полягає в пошуку вашого рядка в басейні стажування, а потім дозволяється сміттєзбірнику утилізувати оригінал. І якщо це рядковий літерал, то він все-таки приходить на практику.
Мені цікаво, чи intern()
можна зловживати шкідливим програмним кодом, щоб виявити, чи існують деякі об'єкти String та їх об'єкти в intern()
пулі, а отже, існують і в іншому місці сеансу Java, коли це не повинно бути відомо. Але це було б можливо лише тоді, коли програмний код уже використовується довірливим способом. І все-таки варто враховувати сторонні бібліотеки, які ви включаєте у свою програму, щоб зберігати та запам'ятовувати свої PIN-номери банкоматів!