Загадка по Java № 1 (boxing и unboxing)

фев 28, 20:43

В каждом языке есть свои маленькие секреты и хитрости, о которых иногда полезно знать. Решил завести себе небольшой цикл для таких хитростей касательно Явы. Ну что ж, поехали!

Прелюдия

Есть код. Нужно ответить, что он выведет.


Integer a = 200;
Integer b = 200;
System.out.println(a == b);

Здесь все просто. Выведет False. Для тех, кто в танке и читают книжки невнимательно, объясню.

Ява сравнивает примитивные типы (byte, short, int, long и т.д.) и объектные (Byte, Short, Integer и Long, соответственно) по разному. У примитивных типов проверяется их значение. У объектных типов проверяется указывают ли они на один и тот же объект. А так как мы создали два разных объекта (пусть даже и с одинаковыми значениями), проверка возвращает False.

Завязка

Теперь немного изменим наш код. Всего лишь уберем по паре нулей у целых чисел. Что выведет?


Integer a = 2;
Integer b = 2;
System.out.println(a == b);

Не буду томить с ответом, выведет — True. Опять же — почему? Чтобы ответить на этот вопрос нужно знать как устроена Ява, а точнее JVM.

Устроена JVM так, как ни странно, что любит оптимизировать и кешировать. По-этому для нужд производительности виртуальная машина кеширует объекты для часто встречающихся примитивов (чисел от -127 до 127, некоторых символов, true и false). Другими словами, когда мы пишем:


Integer a = 2;

новый объект не создается, а берется уже готовый. Откуда? Из кеша. Это естественно повышает производительность наших программ и дает повод для гордости программистам, которые причастились к этой великой тайне.

Итог

Мораль этой истории проста — избегать сравнения объектных типов, соответствующим стандартным примитивам. Лучше приводить их вручную через type casting, а потому уже сравнивать их значения. Так кошернее.

Комментарии

 
---