среда, 22 июня 2011 г.

Ещё 1 проблема автобоксинга


Историческое превью:
Так уж повелось, что Long и long - совершенно разные вещи с абсолютно разным поведением. Ну всякие там возможности/невозможности хранить null-значения, корректность сравнения через оператор == и т.п. В java 1.5 появилась такая фича как автобоксинг. То есть теперь свободно можно писать нечто в стиле:
Long l = 4L;
if (l != 10L) {...}

В то время как раньше приходилось пользовать такой код:
Long l = new Long(4L);
if (l.longValue() != 10L) {...}

По сути, автобоксинг - автоматическое преобразование между классами и примитивными типами. Работает как в одну, так и в другую сторону.


Решение в версиях 1.5 и выше:
Сделать объектный тип из примитивного довольно просто. Просто оборачиваем примитив в конструктор объектного типа:
new Long(4L);
Решение обратной задачи тоже было приведено чуть выше: Просто вместо объекта подставляем его метод longValue().

Проблема:
Long l = null;
if (l != 0L) {...}
Автоматически трансформируется в:
Long l = null;
if (l.longValue() != 0L) {...}

И если во 2 куске кода NullPointerException очевиден, то разглядеть его в первом с непривычки непросто.

Решение:
Внимательность и ещё раз внимательность. Можно писать вот так:
Long l = null;
if (l != null && l != 0L) {...}

Вообще, в JLS говорится о том, что если хоть 1 из операндов сравнения является примитивом, то и второй анбоксится до примитива.

Комментариев нет:

Отправить комментарий