Булево против булево в Java - PullRequest
       28

Булево против булево в Java

163 голосов
/ 16 сентября 2010

Есть дискуссии вокруг Integer против int в Java. По умолчанию первое значение равно null, а во втором - 0. Как насчет Boolean против boolean?

Переменная в моем приложении может иметь значения 0 / 1. Я хотел бы использовать boolean / Boolean и предпочесть не использовать int. Могу ли я использовать Boolean / boolean вместо этого?

Ответы [ 7 ]

232 голосов
/ 16 сентября 2010

Да вместо этого вы можете использовать Boolean / boolean.

Первый - Объект, а второй - примитивный тип.

  • На первом вы получите больше методов, которые будут полезны.

  • Второй - дешевый, учитывая затраты памяти Второй сэкономит вам многобольше памяти, так что дерзайте

Теперь выберите свой путь.

48 голосов
/ 16 сентября 2010

Boolean Обертки тип логического примитива. В JDK 5 и более поздних версиях Oracle (или Sun до того, как Oracle их купил) представила autoboxing / unboxing , что по сути позволяет вам делать это

boolean result = Boolean.TRUE;

или

Boolean result = true; 

Что по сути делает компилятор,

Boolean result = Boolean.valueOf(true);

Итак, для вашего ответа, это ДА.

34 голосов
/ 30 ноября 2012

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

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 показывает, что bar ( boolean ) не может быть неявно преобразован (приведен) в INT .Я говорю об этом не для того, чтобы проиллюстрировать детали реализации JVM, а чтобы подчеркнуть, что с точки зрения низкого уровня (как объем памяти) нужно отдавать предпочтение значениям над безопасностью типов.Особенно, если безопасность этого типа не используется полностью / полностью, как в булевых типах, где проверки выполняются в форме

, если значение \ in {0,1} затем приведено к булевому типу, в противном случае выдается исключение.

Все только для того, чтобы заявить, что {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}.Похоже на излишество, верно?Безопасность типов действительно важна для пользовательских типов, а не для неявного приведения примитивов (хотя последние включены в первый). </p>

Байты не являются типами или битами

Обратите внимание, что в памяти ваша переменная из диапазона {0,1} будет по-прежнему занимать как минимум байт или слово (xbit в зависимости от размера регистра), если специально не позаботиться об этом (например, красиво упаковано в памяти - 8 «логическое значение»)биты в 1 байт - назад и вперед).

Предпочитая безопасность типов (например, помещая / упаковывая значение в ящик определенного типа), а не упаковывая дополнительные значения (например, используя сдвиги битов или арифметику), можноэффективно выбирает написание меньшего кода, чем получение большего объема памяти.(С другой стороны, всегда можно определить пользовательский тип пользователя, который облегчит все преобразования, не соответствующие булевому значению).

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

Наконец, вашвопрос о сравнении ключевого слова с типом .Я считаю, что важно объяснить, почему или как именно вы будете получать производительность, используя / предпочитая ключевые слова («помеченные» как примитив ) над типами (обычные составные определяемые пользователем классы, использующие другое ключевое слово class ) или другими словами

boolean foo = true;

против

Boolean foo = true;

Первая «вещь» (тип) не может быть расширена (подкласс) и не без причины.По сути, терминология Java классов примитивов и обтекания может быть просто переведена в значение inline (LITERAL или константу, которая подставляется напрямую компилятором всякий раз, когда это возможновыведите подстановку или, если нет - все равно вернетесь к переносу значения).

Оптимизация достигается за счет тривиальности:

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

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

Итак, разница между boolean и Boolean точно в Компиляции и Runtime (немного далеко, но почти как instanceof против getClass () ).

Наконец, автобокс медленнее, чем примитивы

Обратите внимание на тот факт, что Java может делать autoboxing - это просто "синтаксический сахар". Это ничего не ускоряет, просто позволяет писать меньше кода. Вот и все. Приведение и упаковка в контейнер информации о типе все еще выполняется. По соображениям производительности выбирайте арифметику, которая всегда будет пропускать дополнительные операции по созданию экземпляров классов с информацией о типах для реализации безопасности типов. Отсутствие типа безопасности - это цена, которую вы платите за повышение производительности. Для кода с булевыми выражениями безопасность типа (когда вы пишете меньше и, следовательно, неявный код) будет иметь решающее значение, например. для управления потоком if-then-else.

16 голосов
/ 16 сентября 2010

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

3 голосов
/ 02 февраля 2016

В основном, логический тип представляет примитивный тип данных, где логический тип представляет эталонный тип данных. эта история начинается, когда Java хочет стать чисто объектно-ориентированной, она предоставляет концепцию класса-оболочки, чтобы не использовать примитивный тип данных.

boolean b1;
Boolean b2;

b1 и b2 не совпадают.

1 голос
/ 12 ноября 2018

Одно наблюдение: (хотя это можно думать о побочном эффекте)

логический будучи примитивом, может сказать да или нет.

Boolean - это объект (он может ссылаться на «да» или «нет» или «не знаю», т. Е. На ноль)

0 голосов
/ 10 декабря 2018

Вы можете использовать Boolean / Boolean. Простота - это путь. Если вам не нужны конкретные 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, когда вам нужен объект, например:

    • Булев поток,
    • Дополнительно
    • Коллекции Булевых
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...