Когда должны использоваться пустые значения 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
ОТВЕТ НА СОБСТВЕННЫЙ ВОПРОС:
Я думал, что было бы полезно ответить на мой собственный вопрос, поскольку я многому научился из ответов. Этот ответ призван помочь тем, кто, как я, не имеет полного понимания проблем. Если я использую неправильный язык, пожалуйста, поправьте меня.
скрывает тот факт, что 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
имеет только два состояния:
Вышеуказанное различие сделает его полезным в списках значений 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 везде, где это возможно. Исключениями из этого может быть устаревшая база данных с нулевыми булевыми столбцами, хотя я бы попытался скрыть это и в моем сопоставлении.