Страницы

Поиск по вопросам

среда, 17 апреля 2019 г.

Обёртка для примитива Boolean как объект

Возможно ли заставить обёртку для примитива Boolean вести себя как объект?
Например, следующий код:
public static void testBoolean(int a, Boolean isLeft) throws Exception { if (a > 3) { isLeft = Boolean.TRUE; } else { isLeft = Boolean.FALSE; } }
public static void main(String[] args) { Boolean isLeft = Boolean.TRUE; testBoolean(5, isLeft); System.out.println(isLeft); testBoolean(1, isLeft); System.out.println(isLeft); }
выводит:
true true
Есть ли какой-либо способ заставить изменяться isLeft в методе testBoolean как объект (чтобы второй раз выводилось false)?


Ответ

Нет, такого способа нету. Объекты ведут себя именно так. Вы спутали со случаем изменения ссылки на объект со случаем изменения (мутации) самого объекта.
В метод testBoolean передаётся ссылка на объект типа Boolean по значению
Внутри метода меняется не сам объект, а лишь ссылка isLeft на него! Поскольку в функцию передаётся лишь копия ссылки (в этом смысл передачи по значению), изменения её снаружи не видны. Вот если бы вы как-то меняли сам объект, то тогда да, его изменения были бы видны снаружи.

Java не поддерживает передачу ссылок по ссылке, но можно сделать грубый хак, и передать вместо ссылки одноэлементный массив:
public static void testBoolean(int a, Boolean[] isLeft) throws Exception { if (a > 3) { isLeft[0] = Boolean.TRUE; } else { isLeft[0] = Boolean.FALSE; } }
https://ideone.com/wa0prq
При этом передаётся копия ссылки на массив, в котором доступен «оригинал» ссылки на Boolean
Точно так же в качестве «контейнера» оригинала ссылки можно использовать AtomicBoolean (но он при этом производит ненужную синхронизацию), ну или самостоятельно написать универсальный контейнер:
class UniversalContainer { T value; public UniversalContainer() {} public UniversalContainer(T initial) { value = initial; } public T get() { return value; } public void set(T value) { this.value = value; } }

public static void testBoolean(int a, UniversalContainer isLeft) { if (a > 3) { isLeft.set(Boolean.TRUE); } else { isLeft.set(Boolean.FALSE); } }
public static void main(String[] args) { UniversalContainer isLeft = new UniversalContainer(Boolean.TRUE); testBoolean(5, isLeft); System.out.println(isLeft.get()); testBoolean(1, isLeft); System.out.println(isLeft.get()); }
https://ideone.com/VwSM19

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

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