Translate

четвер, 4 жовтня 2012 р.

Core: String part 1


Одним з наслідків ресету стане цикл статей про різні аспекти використання JAVA.
В цих статтях я намагатимусь пояснити магію, яка відбувається з кодом.
І звичайно коментарі, зауваження, пропозиці - вітаються!

Отже: Магія 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. Все дуже просто - значення їх однакові.
Знаючи ці речі - бідь-яка співбесіда пройде як по маслу(стосовно питання порівння String) ;)

Продовження буде... (Я сподіваюсь :) )


ПС. Якщо ви помітили помилки чи бажаєте доповнити, пишіть - радо виправлю.

ПС. Важливі ваші відгуки про ініціативу написяння статей і чи стиль написання є доступним.


ВАЖЛИВО: Якщо ви маєте бажання поділитись з оточуючими цікавою інформацією - пишіть!
Наша адреса: bohdan.bandrivskyy@gmail.com чи на адресу блогу jug.lviv@gmail.com
Будь-яка допомога в написанні статті з нашої сторони гарантована.








3 коментарі:

  1. Схожа поведінка є і в об'єкті Integer
    Загалом є правило якого варто дотримуватись.
    Об'єкти ЗАВЖДИ треба порівнювати через equals і тоді ніяких проблем не буде.
    Я б радив уникати без необхідності ігр з пулами.
    http://stackoverflow.com/questions/1514910/when-comparing-two-integers-in-java-does-auto-unboxing-occur

    ВідповістиВидалити
    Відповіді
    1. куди корисніше:)
      http://thedailywtf.com/Articles/Disgruntled-Bomb-Java-Edition.aspx

      Видалити
    2. ))
      Можливо варто нам завести рубрику як варто і не варто робити

      Видалити