Страницы

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

воскресенье, 9 февраля 2020 г.

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

#java


Возможно ли заставить обёртку для примитива 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)?
    


Ответы

Ответ 1



Нет, такого способа нету. Объекты ведут себя именно так. Вы спутали со случаем изменения ссылки на объект со случаем изменения (мутации) самого объекта. В метод 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

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

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