Boolean vs boolean на Java


197

Є дискусії навколо Integerпроти intв Java. Значення за замовчуванням у першого є, nullа в другого - 0. Як щодо Booleanvs boolean?

Змінна в моєму додатку може мати 0/ 1значення. Я хотів би використовувати boolean/ Booleanі вважаю за краще не використовувати int. Чи можу я використовувати Boolean/ booleanзамість цього?


2
З міркувань системи я б вибрав Boolean, оскільки він має опцію "Користувач ще не вирішив", що не дорівнює "істинному", ані "помилковому". Я використовував би булеві примітиви лише у тих випадках, якщо я на 100% впевнений, що правдивих / хибних варіантів достатньо. У базі даних опція NULL зазвичай доступна без проблем (або просто знявши НЕ NULL обмеження на пізніший попит)
CsBalazsHungary

2
Точний дублікат Чому різниця між булевими та булевими в Java? (оскільки GWT не має значення).
Дан Даскалеску

Відповіді:


272

Так, ви можете використовувати Boolean/ booleanзамість цього.

Перший - об'єкт, другий - примітивного типу.

  • Спочатку ви отримаєте більше методів, які будуть корисні.

  • Другий дешевий з огляду на витрату пам’яті . Другий заощадить вам набагато більше пам’яті, тому займіться цим

Тепер виберіть свій шлях.


70
Ви могли б сформулювати це як "другий заощадить вам набагато більше пам’яті, тому продовжуйте це". Корисні методи Boolean можна використовувати, не маючи примірника цього.
DJClayworth

3
Поки ви використовуєте замість Boolean.valueOf (значення) нового Boolean (значення), пам'ять не повинна викликати занепокоєння.
Грег Кейс

2
бо AsyncTaskви можете використовувати лише Booleanзамість boolean.
Раптор

99
Слід зазначити, що булевий фактично має 3 стани ... true, falseа nullтам, де булеві є логічні 2 стани ( trueі false)
поважайте TheCode

14
Булевий - трильян :)
Топера

50

Boolean загортає булівський примітивний тип. У JDK 5 і вище Oracle (або Sun перед тим, як Oracle їх придбав) представив автобокс / розпакування , що по суті дозволяє вам це зробити

boolean result = Boolean.TRUE;

або

Boolean result = true; 

Що по суті робить компілятор,

Boolean result = Boolean.valueOf(true);

Отже, для вашої відповіді - ТАК.


4
Примітка. Ви не завжди можете безпечно призначити Booleanа boolean. Якщо ви Booleanє, nullі ви спробуєте призначити його а boolean, він підкине час NullPointerExceptionвиконання.
Дункан Лука

якщо Booleanклас, то чому значення завжди хибне, навіть якщо я змінив значення з іншого класу, посилаючись на ту саму змінну Boolean? в чому сенс цього, Booleanякщо ми не можемо посилатися на різні класи екземплярів / передавати як аргумент?
user924

знайшов відповідь, ми можемо використовувати AtomicBooleanта посилатися на неї з
різницьких

35

Я трохи розширюю надані відповіді (оскільки поки що вони зосереджуються на своїй "власній" / штучній термінології, орієнтуючись на програмування певної мови, а не дбаючи про більшу картину позаду сцени створення мов програмування , взагалі, тобто коли речі як-от міркування щодо безпеки типу та пам’яті мають значення):

int не булева

Розглянемо

    boolean bar = true;      
    System.out.printf("Bar is %b\n", bar);
    System.out.printf("Bar is %d\n", (bar)?1:0);
    int baz = 1;       
    System.out.printf("Baz is %d\n", baz);
    System.out.printf("Baz is %b\n", baz);

з виходом

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

Java - код на 3 - му рядку (bar)?1:0показує , що бар ( булево ) не може бути неявно перетворений ( з приведенням) в якості міжнар . Я підводжу це не для того, щоб проілюструвати деталі впровадження JVM, а щоб зазначити, що з точки зору низького рівня (як розмір пам'яті) потрібно віддавати перевагу значенням, ніж безпека типу. Особливо, якщо безпека цього типу не справді / повністю використовується, як у булевих типах, де перевірки проводяться у формі

якщо значення \ в {0,1}, тоді буде передано булевий тип, інакше киньте виняток.

Все, щоб стверджувати, що {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Здається, як надмір, так? Безпека типу справді важлива для визначених користувачем типів, а не при неявному відливанні примітивів (хоча останні включаються до першого).

Байти не є типом або бітами

Зауважте, що в пам’яті ваша змінна з діапазону {0,1} все ще буде займати принаймні байт або слово (xbits залежно від розміру регістра), якщо спеціально не береться до уваги (наприклад, добре упаковано в пам'ять - 8 "булевих" біт в 1 байт - вперед і назад).

Віддаючи перевагу безпеці типу (як при введенні / загортанні значення у вікно певного типу) над упаковкою додаткової величини (наприклад, з використанням бітових зрушень або арифметики), ефективно вибирати менше запису коду за рахунок отримання більшої кількості пам'яті. (З іншого боку, завжди можна визначити користувацький тип користувача, який полегшить усі перетворення не варто, ніж Boolean).

ключове слово та тип

Нарешті, ваше питання стосується порівняння ключового слова та типу . Я вважаю, що важливо пояснити, чому або як саме ви отримаєте ефективність, використовуючи / віддаючи перевагу ключові слова ("позначені" як примітивні ) над типами (звичайні складові класи, визначені користувачем, використовуючи інший клас ключових слів ) або іншими словами

boolean foo = true;

vs.

Boolean foo = true;

Перша «річ» (тип) не може бути розширена (підкласична) і не без причини. Ефективно Java-термінологія примітивних та обгорткових класів може бути просто переведена на вбудоване значення (ЛІТЕРАЛЬНА або константа, яка безпосередньо підміняється компілятором, коли можливо зробити висновок про заміну, а якщо ні - все ще резервне перетворення значень).

Оптимізація досягається завдяки тривіальним:

"Менше операцій лиття під час виконання => більша швидкість."

Ось чому, коли зроблено фактичний висновок типу, він може (все-таки) закінчитись примірником класу обгортання з усією інформацією про тип, якщо це необхідно (або перетворенням / виливанням у такі).

Таким чином, різниця між булевих і логічним значенням саме в Збірнику і Час відтворення (трохи далекоглядний , але майже так само InstanceOf проти GetClass () ).

Нарешті, автобоксинг проходить повільніше, ніж примітивні

Зауважте, що Java може робити автобоксинг - це лише «синтаксичний цукор». Це нічого не прискорює, просто дозволяє писати менше коду. Це воно. Відливання та загортання у контейнер для інформації типу все ще виконується. З міркувань продуктивності вибирайте арифметику, яка завжди буде пропускати додаткові послуги по створенню екземплярів класу з інформацією про тип для забезпечення безпеки типу. Відсутність безпеки типу - це ціна, яку ви платите за отримання продуктивності. Для коду з виразами з булевими значеннями тип безпеки (коли ви пишете менше і, отже, неявний код) буде критичним, наприклад, для управління потоками if-then-else.


16

Ви можете використовувати булеві константи - Boolean.TRUEі Boolean.FALSEзамість 0і 1. Ви можете створити свою змінну за типом, booleanякщо примітивним є те, що ви хочете. Таким чином вам не доведеться створювати нові Booleanоб’єкти.


4

Одне зауваження: (хоча це можна вважати побічним ефектом)

булева буття примітиву може сказати "так" або "ні".

Булевий об'єкт (це може позначати або так, ні, або "не знаю", тобто нульовий)


3

В основному булеві символи являють собою примітивний тип даних, де булеві символи представляють тип опорних даних. ця історія починається тоді, коли Java хочуть стати об'єктно орієнтованими, вона надала концепцію класу обгортки, щоб перейти на використання примітивного типу даних.

boolean b1;
Boolean b2;

b1і b2не однакові.


1

Можна використовувати булеву / булеву. Простота - це шлях. Якщо вам не потрібні конкретні api (Колекції, Потоки тощо) і ви не передбачаєте, що вони вам знадобляться - використовуйте примітивну її версію (булева).

  1. За допомогою примітивів ви гарантуєте, що не передасте нульові значення.
    Ви не потрапите в подібні пастки. Нижче наведений код кидає NullPointerException (від: булеві, умовні оператори та автобоксинг ):

    public static void main(String[] args) throws Exception { Boolean b = true ? returnsNull() : false; // NPE on this line. System.out.println(b); } public static Boolean returnsNull() { return null; }

  2. Використовуйте Boolean, коли вам потрібен об'єкт, наприклад:

    • Потік булевих,
    • За бажанням
    • Колекції булевих
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.