Когда должны использоваться пустые значения Boolean?

Java boolean допускает значения true и false, тогда как Boolean допускает true, false и null. Я начал конвертировать мои boolean в boolean s. Это может привести к сбоям в тестах, таких как

Boolean set = null;
...
if (set) ...

в то время как тест

if (set != null && set) ...

кажется надуманным и подверженным ошибкам.

Когда, если когда-либо, полезно использовать boolean с нулевыми значениями? Если никогда, то каковы основные преимущества обернутого объекта?

UPDATE: Было так много ценных ответов, что я обобщил некоторые из них в своем собственном ответе. Я нахожусь в лучшем случае промежуточным звеном на Java, поэтому я попытался показать то, что мне кажется полезным. Обратите внимание, что вопрос "неправильно сформулирован" (Boolean не может иметь "нулевое значение" ), но я оставил его, если другие имеют такое же заблуждение

Ответ 1

Используйте boolean, а не boolean каждый раз, когда сможете. Это позволит избежать многих NullPointerException и сделать ваш код более надежным.

boolean полезен, например

  • для хранения булевых элементов в коллекции (список, карта и т.д.).
  • для представления нулевых булевых (например, исходящих из нулевого булева столбца в базе данных). Нулевое значение может означать "мы не знаем, истинно это или ложно" в этом контексте.
  • каждый раз, когда методу нужен объект как аргумент, и вам нужно передать логическое значение. Например, при использовании отражения или методов типа MessageFormat.format().

Ответ 2

Я почти никогда не использую Boolean, потому что его семантика расплывчата и неясна. В принципе у вас есть логика с тремя состояниями: истина, ложь или неизвестность. Иногда полезно использовать его, когда, например, вы дали пользователю выбор между двумя значениями, и пользователь вообще не ответил, и вы действительно хотите знать эту информацию (подумайте: столбец базы данных NULLable).

Я не вижу причин для преобразования из Boolean в Boolean, поскольку он вводит дополнительные накладные расходы памяти, возможность NPE и меньшее количество ввода. Обычно я использую неудобный BooleanUtils.isTrue(), чтобы сделать мою жизнь немного легче с помощью Boolean.

Единственной причиной существования Boolean является возможность иметь коллекции типа Boolean (generics не позволяют Boolean, а также все остальные примитивы).

Ответ 3

Ничего себе, что же? Это только я или все эти ответы ошибочны или, по крайней мере, вводят в заблуждение?

Булевский класс является оберткой вокруг булева примитивного типа. Использование этой обертки должно иметь возможность передавать логическое значение в методе, который принимает объект или общий. Т.е. вектор.

Логический объект никогда не может иметь значение null. Если ваша ссылка в Boolean равна null, это просто означает, что ваш Boolean никогда не был создан.

Вы можете найти это полезным: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

Нулевая булева ссылка должна использоваться только для запуска аналогичной логики, к которой у вас есть другая нулевая ссылка. Использование его для трех логических состояний неудобно.

EDIT: обратите внимание, что Boolean a = true; является вводящим в заблуждение оператором. Это действительно соответствует чему-то ближе к Boolean a = new Boolean(true); Пожалуйста, смотрите здесь autoboxing: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Autoboxing

Возможно, именно здесь происходит большая путаница.

EDIT2: Пожалуйста, прочитайте комментарии ниже. Если кто-то имеет представление о том, как реструктурировать мой ответ, чтобы включить это, сделайте это.

Ответ 4

Есть три причины:

  • для представления логических значений базы данных, которые могут быть true, false или null
  • для представления значений XML-схемы xsd:boolean, объявленных с помощью xsd:nillable="true"
  • чтобы иметь возможность использовать общие типы: List<Boolean> - вы не можете использовать List<Boolean>

Ответ 5

ОТВЕТ НА СОБСТВЕННЫЙ ВОПРОС: Я думал, что было бы полезно ответить на мой собственный вопрос, поскольку я многому научился из ответов. Этот ответ призван помочь тем, кто, как я, не имеет полного понимания проблем. Если я использую неправильный язык, пожалуйста, поправьте меня.

  • Значение "null" не является значением и принципиально отличается от true и false. Это отсутствие указателя на объекты. Поэтому думать, что булевы 3-значные в корне неверны
  • Синтаксис для Boolean сокращен и скрывает тот факт, что ссылка указывает на Objects:

    Boolean a = true;

скрывает тот факт, что true является объектом. Другие эквивалентные задания могут быть:

Boolean a = Boolean.TRUE;

или

Boolean a = new Boolean(true);
  • Сокращенный синтаксис

    if (a) ...

отличается от большинства других назначений и скрывает тот факт, что a может быть ссылкой на объект или примитив. Если объект необходимо проверить на null, чтобы избежать NPE. Для меня психологически легче запомнить это, если есть тест равенства:

if (a == true) ...

где нам может быть предложено проверить значение null. Таким образом, укороченная форма безопасна только тогда, когда a является примитивным.

Для себя у меня теперь есть рекомендации:

  • Никогда не используйте null для 3-значной логики. Используйте только true и false.
  • НИКОГДА не возвращайте Boolean из метода, поскольку это может быть null. Верните только Boolean.
  • Используйте только Boolean для обертывания элементов в контейнерах или аргументов методам, в которых требуются объекты

Ответ 6

Классы Wrapper для примитивов могут использоваться там, где требуются объекты, коллекции - хороший образец.

Представьте, что вам почему-то нужно хранить последовательность boolean в ArrayList, это может быть сделано с помощью бокса boolean в boolean.

Несколько слов об этом здесь

Из документации:

Как любой программист Java знает, вы не можете положить int (или другой примитив значение) в коллекцию. Коллекции могут содержать только ссылки на объекты, поэтому вам нужно вставить примитивные значения в соответствующий класс-оболочку (который является Integer в случае int). Когда вы вынимаете объект из в коллекции вы получите Integer, который вы положили; если вам понадобится int, вы должны распаковать Integer, используя метод intValue. Все это бокс и unboxing - это боль, и загромождает ваш код. функция автобоксинга и распаковки автоматизирует процесс, устраняя боль и беспорядок.

http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

Ответ 7

Я предполагаю, что в каком-то случае у вас должен быть механизм, чтобы отличить логическое поле, которое уже задало значение или нет.

Ответ 8

Boolean Обертка полезна, когда вы хотите, чтобы значение было присвоено или не было отделено от true и false. Он имеет следующие три состояния:

  • True
  • False
  • Не задано null

В то время как Boolean имеет только два состояния:

  • True
  • False

Вышеуказанное различие сделает его полезным в списках значений Boolean, которые могут иметь true, false или null.

Ответ 9

Основная цель для Boolean - это нулевое значение. Значение Null говорит, что это свойство undefined, например, взять столбец с нулевым значением базы данных.

Если вам действительно нужно преобразовать все значения из примитивного логического в wrapper Boolean, вы можете использовать следующий код для поддержки старого кода:

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...

Ответ 10

Существует много применений для значения ** null ** в булевой оболочке!:)

Например, у вас может быть поле с названием "информационный бюллетень", указывающее, хочет ли пользователь или не хочет получать информационный бюллетень с вашего сайта. Если пользователь не выбирает значение в этом поле, возможно, вам захочется применить поведение по умолчанию к этой ситуации (отправить "Не отправлять", "Повторить вопрос?" И т.д.). Очевидно, что не задано (или не выбрано или ** null **), это не то же самое, что true или false.

Но если "not set" не относится к вашей модели, не изменяйте логический примитив;)

Ответ 11

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

Итак, в не совершенном мире, в котором мы живем, булевский объект велик, поскольку он может представлять отсутствующее или неизвестное состояние как null. В конце концов, компьютеры просто моделируют реальный мир, и должны учитывать все возможные состояния и обрабатывать их с помощью исключений исключения (в основном, поскольку существуют случаи, когда выбрасывание исключения будет правильным ответом).

В моем случае логический объект был идеальным ответом, поскольку в исходном XML иногда отсутствовал элемент, и я все равно мог получить значение, назначить его логическому, а затем проверить нуль, прежде чем пытаться использовать true или false протестируйте его.

Только мои 2 цента.

Ответ 12

Для всех хороших ответов выше я просто приведу конкретный пример в Java servlet HttpSession class. Надеемся, что этот пример поможет прояснить некоторые вопросы, которые могут возникнуть у вас.

Если вам нужно сохранить и получить значения для сеанса, вы используете метод setAttribute (String, Object) и getAttribute (String, Object). Таким образом, для логического значения вы вынуждены использовать Boolean-класс, если хотите сохранить его в сеансе http.

HttpSession sess = request.getSession(false);
Boolean isAdmin = (Boolean) sess.getAttribute("admin");
if (! isAdmin) ...

Последняя строка вызовет NullPointerException, если значения атрибута не установлены. (вот почему я привел меня на этот пост). Итак, логическое состояние 3 здесь, чтобы остаться, предпочитаете ли вы его использовать или нет.

Ответ 13

Boolean может быть очень полезным, когда вам нужно три состояния. Как и при тестировании программного обеспечения, если Test прошел, отправьте true, если не удалось отправить false, и если тестовый случай прерван, отправьте null, который будет обозначать тестовый случай, который не был выполнен.

Ответ 14

Лучший способ состоял бы в том, чтобы полностью исключить логические значения, поскольку каждый логический смысл подразумевает, что у вас есть условное выражение где-либо еще в вашем коде (см. http://www.antiifcampaign.com/ и этот вопрос: Можете ли вы написать любой алгоритм без оператора if?).

Однако, прагматично, вы должны время от времени использовать логические значения, но, как вы уже узнали сами, обработка Booleans более подвержена ошибкам и громоздка. Поэтому я предлагаю использовать boolean везде, где это возможно. Исключениями из этого может быть устаревшая база данных с нулевыми булевыми столбцами, хотя я бы попытался скрыть это и в моем сопоставлении.