Магія String Об'экт/не об'єкт
Хоч String і є об'єктом, але він є immutable і створююється новий об'єкт і референс на старий об'єкт перетираються.
На консолі буде виведено:public class StringObject { public static void main(String[] args) { String val ="object"; updateString(val); System.out.println(val); } private static void updateString(String val) { val ="not object"; System.out.println(val); } }
not object
object
Отже:
Магія String Concatenation
Всі знають (ну майже всі), що для додавання стрінгів треба використовувати спеціальні класи, але на скільки це критично мало хто задумується...
public class StringPerformance { public static void main(String[] args) { long start = System.nanoTime(); badMethod("Test Message", "Watery Lane"); long duration = System.nanoTime() - start; System.out.println("Using Strings took " + duration + "nS"); start = System.nanoTime(); StringBufferMethod("Test Message", "Watery Lane"); duration = System.nanoTime() - start; System.out.println("Using StringBuffer took " + duration + "nS"); start = System.nanoTime(); StringBuilderMethod("Test Message", "Watery Lane"); duration = System.nanoTime() - start; System.out.println("Using StringBuilder took " + duration + "nS"); } private static String badMethod(String message, String location) { String str = "Exception closing down "; str += message; str += " at "; str += location; str += " Press any key to exit"; return str; } private static String StringBufferMethod(String message, String location) { StringBuffer str = new StringBuffer("Exception closing down "); str.append(message); str.append(" at "); str.append(location); str.append(" Press any key to exit"); return str.toString(); } private static String StringBuilderMethod(String message, String location) { StringBuilder str = new StringBuilder("Exception closing down "); str.append(message); str.append(" at "); str.append(location); str.append(" Press any key to exit"); return str.toString(); } }
На моєму Intel i5 я отримав:
Using Strings took 73912nS
Using StringBuffer took 26563nS
Using StringBuilder took 10394nS
Продуктивність String vs StringBuilder вражаюча 700% на користь StringBuilder. Отже дуже раджу не лінитисьі використовувати StringBuilder!
Стосовно StringBuilder vs StringBuffer, то на перший погляд тут також просто - StringBuffer Thread safe. StringBuffer обов'язково потрібно використовувати, коли ви маєте багатопотокову систему.
Але от коли у вас не багатопотокова система, то тут не все так однозначно. В Java є така магічна річ як JIT, яка може видалити сихронізацію потоків і вирівняти продуктивнсть. Тож не потрібно обов'язково заміняти в легасі коді StringBuilder на StringBuilde, можливо, синхронізація і так видаляється.
Магія String Utils.
Клас String має достатньо багато інструментів, які нам допомагають зробити дуже багато речей найоптимальнішим шляхом, також Java має цілий набір класів які допомагають в маніпулюванні стрінгами. Але я б радив вам звернути увагу на сет спеціалізованих бібліотек, які ще більше полегшать життя кожному:-Apache Commons - тут можна знайти цілу купу надзвичайно корисних дрібничок
-Google Guava - просто фантастична кількість утилітних класів
-Spring Utils - ще один додаток, який робить світ Spring самодостаттнім.
ПС: Як написано нижче - ми намагаємось освіжити JUG і зробити його актуальнішим, але без ваших відгукув - це неможливо!!! Чекаємо на ваші думки, побажання, пропозиції ось тут: http://jug-lviv.blogspot.com/2012/10/jug-reset.html
взагалі то перший приклад демонструє факт копіювання по значенню (проти референсу), а зовсім не іммутабельність стрінга
ВідповістиВидалитиНажаль Костянтин мушу з тобою не погодитись.
ВідповістиВидалитиЦе достатньо складна тема і я не знайшов ні одного посилання, де б прямо говорилось, що стрінг передається за значенням.
Ось приклад статті: http://www.coderanch.com/t/392784/java/java/Passing-String-reference
Як я розумію, то в методі створюється копія посилання (4 байти), які вказують на об"єкт, коли ми робимо val ="not object"; в змінна переписується нова адреса на новий об"єкт.
Якщо матимеш посилання на це - радо почитаю і зміню свою думку.
>>> в змінна переписується нова адреса на новий об"єкт
Видалитисаме це мав на увазі Костянтин, а отже жодного натяку на імутабельність.
хорошим прикладом імутабельності, натомість, могли б бути BigDecimal або якийсь із класів часу або дати у joda-time. Особливо беручи до уваги їхні методи додавання, віднімання і т.д.
Перш за все кульно - хтось читає моє писалово:).
ВідповістиВидалитиСтосовно Констянтина, то питання було в тому як передається значення в метод.
А стосовно імутабле, то тут погоджуюсь не зовсі зрозуміло висловився - перепишу.
ПС. Може хтось матиме бажання ще щось написати ? :)
When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor.
ВидалитиJava Language Specification http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.1
Автор видалив цей коментар.
Видалитияк такого - питання не було. я лише зауважив, що перший приклад не ілюструє імутабільність стрінгів, а є чудовим прикладом pass-by-value
ВидалитиДякую за коменти. Просто вреженний - це блог хтось читає :).
ВідповістиВидалитиЯк я казав виправлю :)
читають :)
Видалититре періодично щось суперечливе постати, щоб активізувати блог ;)