В цих статтях я намагатимусь пояснити магію, яка відбувається з кодом.
І звичайно коментарі, зауваження, пропозиці - вітаються!
Отже: Магія String part 1
Як ви знаєте String в Java це об'єкт для маніпуляції із масивами символів. Але не все так просто.
Магія String Immutable.
Що це означає? це означає:String a ="1"; System.out.println(a.hashCode()); a = a+"No."; System.out.println(a.hashCode());
(Hash code змінився)
Кожного разу, коли ви 'змінюєте' значення String - створюється новий об'єкт.
Тобто стрічка коду a = a+"No." не змінить значення поточного об'єкта, а створить новий об'єкт.
Ви запитаєте чому immutable? Причиною цьому є місце, де зберігаються стрінги String pool - це реалізація патерна Flyweight. Якщо б String не був би immutable, тоді б при зміні значення однієї із змінних, які вказують на об'єкт в пулі - всі інші також б змінювались, що є недоступним.
ПС .Потрібно бути обережним при конкатeнації стрінгів. Необережне поводження з ними може привести до java.lang.OutOfMemoryError.
Магія String. Порівння.
Порівняння String це мабуть улюбленне питання на всіх співбесідах і ось приклад того, що можна зустріти як запитання:
String str1 = "JUG";
String str2 = "JUG";
String str3 = new String("JUG");
System.out.println("str1 == str2 is " + (str1 == str2));
System.out.println("str1 == str3 is " + (str1 == str3));
System.out.println("str1.intern() == str3.intern() is " +
(str1.intern() == str3.intern()));
System.out.println(" ");
System.out.println("str1.equals(str2) is " + str1.equals(str2));
System.out.println("str1.equals(str3) is " + str1.equals(str3));
System.out.println("str1.intern().equals(str3.intern()) is " +
str1.intern().equals(str3.intern()));
System.out.println(" ");
System.out.println("str1.hashCode() "+str1.hashCode());
System.out.println("str2.hashCode() "+str2.hashCode());
System.out.println("str3.hashCode() "+str3.hashCode());
Тут треба розуміти декілька речей:- В залежності як створюється String - він знаходиться в різний обласях пам'яті JVM:
- літерали (String str1 = "JUG";) знаходитсья в String pool в якому зберігаються значення, що дозволяє уникнути дублювання значень
- обє'кти (new String("JUG")) зберігаються в heap
- Порівння через '==' робить порівння об'єктів, якщо у варіанті str1 і str2 порівнюється один і той ж об'єкт в String pool, то порівння str1 і str3 порівнюється об'єкт з String pool і heap. Тобто два різні об'єкти
- Порівняння через 'equals' - порівнює значення об'єктів.
- Метод intern. Він створює в String pool об'єкт зі значенням, яке має об'єкт з heap(якщо такого там ще нема). Цей метод має багато підводних камнів які описанні ось тут:http://habrahabr.ru/post/79913/
- hashCode - однакивий у str1, str2 і str3. Все дуже просто - значення їх однакові.
Продовження буде... (Я сподіваюсь :) )
ПС. Якщо ви помітили помилки чи бажаєте доповнити, пишіть - радо виправлю.
ПС. Важливі ваші відгуки про ініціативу написяння статей і чи стиль написання є доступним.
ВАЖЛИВО: Якщо ви маєте бажання поділитись з оточуючими цікавою інформацією - пишіть!
Наша адреса: bohdan.bandrivskyy@gmail.com чи на адресу блогу jug.lviv@gmail.com
Будь-яка допомога в написанні статті з нашої сторони гарантована.
Схожа поведінка є і в об'єкті Integer
ВідповістиВидалитиЗагалом є правило якого варто дотримуватись.
Об'єкти ЗАВЖДИ треба порівнювати через equals і тоді ніяких проблем не буде.
Я б радив уникати без необхідності ігр з пулами.
http://stackoverflow.com/questions/1514910/when-comparing-two-integers-in-java-does-auto-unboxing-occur
куди корисніше:)
Видалитиhttp://thedailywtf.com/Articles/Disgruntled-Bomb-Java-Edition.aspx
))
ВидалитиМожливо варто нам завести рубрику як варто і не варто робити