Вопрос по java, boolean – Когда следует использовать нулевые значения Boolean?

150

Джаваboolean позволяет значенияtrue а такжеfalse в то время как логическое позволяетtrue, false, а такжеnull, Я начал конвертировать моиbooleanсBooleans. Это может вызвать сбои в таких тестах, как

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

пока тест

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

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

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

ОБНОВИТЬ: Было так много ценных ответов, что я суммировал некоторые из них в своем собственном ответе. Я в лучшем случае являюсь промежуточным звеном в Java, поэтому я попытался показать то, что мне показалось полезным. Обратите внимание, что вопрос «неправильно сформулирован» (Логическое значение не может иметь «нулевое значение»), но я оставил его на тот случай, если у других будет такое же заблуждение

& Quot; всегда & Quot; является немного сильным, что я не смею подтверждать, но я ожидаю, что тест наnull если это действительно используется в качестве третьего состояния. nhahtdh
Вы также можете проверить это:thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx biziclop
У вас есть причина для преобразования логических значений в логические? Я придерживаюсь примитивного типа и обертываю его, только если для этого есть веская причина, например когда мне нужно передать переменную по ссылке. jpe
Иногда требуется неинициализированное состояние и настройкаBoolean переменная кnull помогает. nhahtdh
Нет такого понятия, как "нулевое значение"in логическое значение.Boolean является объектом, аboolean является "скалярным". ЕслиBoolean ссылка установлена на ноль, что означает, что соответствующийBoolean объект не существует. Вы не можете помещать что-либо внутри чего-то, что не существует. Hot Licks

Ваш Ответ

14   ответов
1

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

Не лучше ли для этого перечисления? В отличие от возможной выдачи неожиданных исключений NullPointerException для клиента, перечисления явно определяют «состояния»
ум, чтобы уточнить?
24

to represent Database boolean values, which may be true, false or null to represent XML Schema's xsd:boolean values declared with xsd:nillable="true" to be able to use generic types: List<Boolean> - you can't use List<boolean>
@MichalB. Sybase (и SQL Server) битовый типinfocenter.sybase.com/help/index.jsp?topic=/…
Какая база данных не допускает null для логического значения? Если вы установите для столбца значение NULL, тип данных больше не имеет значения ...
Я "явно написал" логическое значение ", а не"boolean& Quot; (стиль мышления), потому что в Oracle вы обычно используетеchar(1) null с "T" и "F"; ценности. Таким образом, он может (например, с адаптером типа Hibernate) быть нулевым :)
@Mark - нет, SQL Server допускает нулевой бит -msdn.microsoft.com/en-us/library/ms177603.aspx
1

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

Если вам нужно сохранить и получить значения для сеанса, вы используетеsetAttribute(Строка, Объект) иgetAttribute(String, Object) метод. Поэтому для логического значения вы вынуждены использовать логический класс, если хотите сохранить его в сеансе http.

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

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

1

евой оболочке! :)

Например, вы можете иметь в форме поле с именем & quot; newsletter & quot; которые указывают, хочет ли пользователь или не хочет получать новостную рассылку с вашего сайта. Если пользователь не выбирает значение в этом поле, вы можете захотеть реализовать поведение по умолчанию для этой ситуации (отправить «не отправлять», «вопрос снова» и т. Д.). Понятно, что не установлено (или не выбрано, или ** null **), это не то же самое, что true или false.

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

3

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

True False Not defined which is null

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

True False

Вышеуказанная разница сделает это полезным в спискахBoolean значения, которые могут иметьTrue, False или жеNull.

Я имел в виду, что Bolean можно использовать для определения True / False и Not Defined.
Нет, он не имеет нулевого состояния, которое является ссылкой.
11

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

The null "value" is not a value and is fundamentally different from true and false. It is the absence of a pointer to objects. Therefore to think that Boolean is 3-valued is fundamentally wrong

The syntax for Boolean is abbreviated and conceals the fact that the reference points to Objects:

Boolean a = true;

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

Boolean a = Boolean.TRUE;

или же

Boolean a = new Boolean(true);

The abbreviated syntax

if (a) ...

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

if (a == true) ...

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

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

Never use null for a 3-valued logic. Only use true and false. NEVER return Boolean from a method as it could be null. Only return boolean. Only use Boolean for wrapping elements in containers, or arguments to methods where objects are required
Не используйте «новый логический (любой)». Это создаст новый логический элемент в куче. Тем не менее, логическое значение является неизменным. Используйте & quot; Boolean.valueOf (что угодно) & quot; который создаст ссылку, которая указывает либо на Boolean.TRUE, либо на Boolean.False, в зависимости от чего бы то ни было.
Одной из многих проблем с Java (IMHO после 12 лет) является несоответствие подхода к нулевым значениям, которое также имеют старые языки. Взглянув на Scala, он имеет концепцию типизированного Option, который может быть нулевым или иметь значение (подклассы None или Some). Затем вы можете вызвать myOption.getOrElse (defaultValue). Увидетьscala-lang.org/api/current/scala/Option.html в этом нет ничего сложного. Тем не менее, поскольку он встроен в новый язык JVM, многие библиотеки используют его. Это делает шкалу "исправлять" некоторые из "прошлого века" проблема Java, но она все еще компилируется в файлы классов, которые работают на JRE.
31

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

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

Логический объект НИКОГДА не может иметь значение null. Если твойreference логическое значение равно нулю, это просто означает, что ваш логический код не был создан.

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

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

РЕДАКТИРОВАТЬ: обратите внимание, чтоBoolean a = true; вводящее в заблуждение утверждение. Это действительно что-то ближе кBoolean a = new Boolean(true); Пожалуйста, смотрите автобокс здесь:http://en.wikipedia.org/wiki/Boxing_%28computer_science%,29#Autoboxing

Возможно, отсюда и большая часть путаницы.

РЕДАКТИРОВАТЬ 2: Пожалуйста, прочитайте комментарии ниже. Если у кого-то есть идея, как изменить мой ответ, чтобы включить это, сделайте это.

Когда вы делаетеBoolean a; a - указатель на логический объект. если тыa = null; Вы не установили свой логический элемент на ноль, вы установили ссылку на ноль. ДелатьBoolean a = null; a.booleanValue(); В этом случае выnever even created логический объект и, следовательно, он выдаст исключение nullpointerexception. Дайте мне знать, если вам нужна дополнительная инструкция.
Вы упускаете мою точку зрения @missingno. Я согласен, что нам нужно учитывать нулевые ссылочные значения. Я никогда не спорил против этого. Но мы должны сделать это дляANY OBJECT REFERENCE. Нулевая логическая ссылка не является особым случаем. И, следовательно, нулевые булевы ссылочные значения не требуют специального рассмотрения.
@missingno, весь код, который имеет дело с любым объектом, должен иметь дело с этим. Ссылка на объект может быть либо нулевой, либо нет. Это не особый случай и не требует особого рассмотрения.
Далее, когда вы делаетеBoolean a = true;, Это делает какую-то магию, которая на самом деле интерпретируется какBoolean a = new Boolean(true); Это, вероятно, не совсем правильно по соображениям производительности, но вы должны понимать, что логическое значение все еще является объектом.
Я не понимаю вашего утверждения "Логическое значение НИКОГДА не может иметь значение null". Я могу создать логическое значение (Boolean a = true;) и затем установите в ноль (a = null;). Это может быть не элегантно или мудро, но это возможно. peter.murray.rust
236

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

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

to store booleans in a collection (List, Map, etc.) to represent a nullable boolean (coming from a nullable boolean column in a database, for example). The null value might mean "we don't know if it's true or false" in this context. each time a method needs an Object as argument, and you need to pass a boolean value. For example, when using reflection or methods like MessageFormat.format().
Перегрузка понятия нуля значением, отличным от «вселенная не знает». это слабее, чем использование 3 (или более) значного перечисления. Делает чтение кода, передавая параметры в метод, также более явным.
Нулевое значение в базе данных также может означать"FileNotFound"
Другое использование для Boolean, которое я имел, было в качестве параметра универсального типа при расширении универсальных классов - тесно связанного с пунктом 3.
Или № 4:Boolean isSchrodinger‎CatAlive = null; (извините, не смог устоять;)).
Думаю, ваша вторая пуля действительно является основой правильного ответа на этот вопрос.
53

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

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

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

Для многозначной логики предпочтительно использовать перечисления. Таким образом, логическое значение должно быть оставлено для (авто) переменных бокса для использования в структурах данных.
+1 заBooleanUtils.isTrue() с которым я не сталкивался peter.murray.rust
При использовании Boolean удобным тестом для исключения исключений нулевого указателя являетсяBoolean.TRUE.equals(myBooleanObject) или жеBoolean.FALSE.equals(myBooleanObject).
Оставьте Apache Commons, чтобы быть похожим на "Кто-то может испортить оценку булевых значений ... давайте сделаемisTrue() Способ ... & Quot; это звучит как самая глупая вещь в истории функций утилит. И все же, каким-то образом, это полезно ... это самый большой вес здесь.
Логический объект имеет только два состояния:true а такжеfalse. null являетсяnot состояние объекта, а скорее состояние ссылки на объект.
10

где требуются объекты, и коллекции являются хорошим примером.

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

Есть несколько слов об этомВот

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

As any Java programmer knows, you can’t put an int (or other primitive value) into a collection. Collections can only hold object references, so you have to box primitive values into the appropriate wrapper class (which is Integer in the case of int). When you take the object out of the collection, you get the Integer that you put in; if you need an int, you must unbox the Integer using the intValue method. All of this boxing and unboxing is a pain, and clutters up your code. The autoboxing and unboxing feature automates the process, eliminating the pain and the clutter.

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

1

е.Null value says, that property is undefinedНапример, возьмите столбец базы данных, обнуляемый.

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

Boolean set = Boolean.FALSE; //set to default value primitive value (false)
...
if (set) ...
«Основная цель - нулевое значение». Нет, основная цель Boolean - передать ссылку на Boolean как объект.
@ user606723 согласился, я имел в виду случай с базой данных, когда писал.
0

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

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

Не ответ на вопрос.
@MisterSmith Imho логический флаг часто неправильно используется как переменная проверки типа, поэтому ссылка также может применяться здесь. Это должен быть просто намек на то, что следует подумать о том, является ли логическое значение правильным инструментом в определенной ситуации. Утверждение «полностью избегать логических выражений» конечно очень радикально и практически невозможно, поэтому я добавил второй абзац. Я также добавил «более подверженный ошибкам и более громоздкий» уточнить вещи.
Работа с логическими значениями так же подвержена ошибкам, как и работа с любым другим объектом. Кстати, ссылка против распространения IF для проверки типа, а не для общего использования. И, в свою очередь, это «опасно» потому что это делает модификации более сложными. Так что нет ничего плохого в IF как таковых.
1

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

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

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

Просто мои 2 цента.

3

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

Похожие вопросы