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

217
16 ноября 2017, 02:37

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

Answer 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> {
    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<Boolean> isLeft) {
    if (a > 3) {
        isLeft.set(Boolean.TRUE);
    } else {
        isLeft.set(Boolean.FALSE);
    }
}
public static void main(String[] args) {
    UniversalContainer<Boolean> isLeft = new UniversalContainer<Boolean>(Boolean.TRUE);
    testBoolean(5, isLeft);
    System.out.println(isLeft.get());
    testBoolean(1, isLeft);
    System.out.println(isLeft.get());
}

https://ideone.com/VwSM19

READ ALSO
Преобразовать XSSFWorkbook в SXSSFWorkbook

Преобразовать XSSFWorkbook в SXSSFWorkbook

У меня есть метод для записи данный в эксель файлОн при больших значениях падает с ошибкой - нехватка памяти

325
Несколько реализаций для одного класса

Несколько реализаций для одного класса

Для android существует такая вещь как ProductFlavorsХочется получиться тоже самое и для простой java и в итоге получить jar'ник

218
LibGDX (де)активация кнопки

LibGDX (де)активация кнопки

Изучал раньше Android там можно было сделать кнопку неактивной (setEnabled) , так вот как в libGDX такое реализовывается ? Уже есть что то готовое или самому...

236