Java boolean
pozwala na wartości true
, a false
jednocześnie pozwala logiczna true
, false
i null
. Zacząłem konwertować moje boolean
s na Boolean
s. Może to powodować awarie w testach, takich jak
Boolean set = null;
...
if (set) ...
podczas testu
if (set != null && set) ...
wydaje się wymyślony i podatny na błędy.
Kiedy, jeśli w ogóle, warto używać Boolean
s z wartościami null? Jeśli nigdy, to jakie są główne zalety opakowanego przedmiotu?
AKTUALIZACJA: Było tak wiele cennych odpowiedzi, że niektóre z nich podsumowałem we własnej odpowiedzi. Jestem co najwyżej średniozaawansowanym w Javie, więc starałem się pokazać rzeczy, które uważam za przydatne. Zwróć uwagę, że pytanie jest „niepoprawnie sformułowane” (wartość logiczna nie może „mieć wartości zerowej”), ale zostawiłem je na wypadek, gdyby inni mieli to samo błędne przekonanie
Boolean
zmiennejnull
pomaga.null
jeśli rzeczywiście jest używany jako trzeci stan.Boolean
jest obiektem, podczas gdy aboolean
jest „skalarem”. JeśliBoolean
odniesienie ma wartość null, oznacza to, że odpowiedniBoolean
obiekt nie istnieje. Nie możesz umieścić niczego w czymś, co nie istnieje.Odpowiedzi:
Używaj
boolean
zamiast zaBoolean
każdym razem, gdy możesz. Pozwoli to uniknąć wieluNullPointerException
s i sprawi, że Twój kod będzie bardziej niezawodny.Boolean
jest przydatny na przykładMessageFormat.format()
.źródło
Boolean isSchrodingerCatAlive = null;
(przepraszam, nie mogłem się oprzeć;)).Prawie nigdy nie używam,
Boolean
ponieważ jego semantyka jest niejasna i niejasna. Zasadniczo masz logikę 3-stanową: prawda, fałsz lub nieznane. Czasami jest to przydatne, gdy np. Dałeś użytkownikowi wybór między dwiema wartościami, a użytkownik w ogóle nie odpowiedział i naprawdę chcesz poznać tę informację (pomyśl: kolumna bazy danych NULLable).Nie widzę powodu, aby konwertować z
boolean
na,Boolean
ponieważ wprowadza to dodatkowe obciążenie pamięci, możliwość NPE i mniej pisania. Zwykle używam niezręczności,BooleanUtils.isTrue()
aby ułatwić sobie życieBoolean
.Jedynym powodem istnienia
Boolean
jest możliwość posiadania kolekcjiBoolean
typu (typy generyczne nie pozwalająboolean
, a także wszystkie inne prymitywy).źródło
Boolean.TRUE.equals(myBooleanObject)
lubBoolean.FALSE.equals(myBooleanObject)
.true
ifalse
.null
to nie stan obiektu, ale raczej stan odwołania do obiektu.isTrue()
metodę…”, co brzmi jak najgłupsza, dziwaczna rzecz w historii funkcji użytkowych. A jednak w jakiś sposób jest to przydatne ... to największy wtf tutaj.Wow, co u licha? Czy to tylko ja, czy wszystkie te odpowiedzi są błędne lub przynajmniej mylące?
Klasa Boolean jest opakowaniem otaczającym typ pierwotny boolowski. Zastosowanie tego opakowania ma na celu przekazanie wartości logicznej w metodzie, która akceptuje obiekt lub rodzaj. Tj. Wektor.
Obiekt boolowski NIGDY nie może mieć wartości null. Jeśli twoje odniesienie do wartości Boolean jest zerowe, oznacza to po prostu, że twoja wartość Boolean nigdy nie została utworzona.
Może Ci się to przydać: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java
Null Boolean Reference powinien być używany tylko do wyzwalania podobnej logiki, do której masz jakiekolwiek inne zerowe odniesienie. Używanie go do logiki trzech stanów jest niezdarne.
EDYCJA: uwaga, to
Boolean a = true;
jest mylące stwierdzenie. To naprawdę oznacza coś bliższego.Boolean a = new Boolean(true);
Zobacz autoboxing tutaj: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#AutoboxingByć może jest to przyczyna zamieszania.
EDYCJA2: Przeczytaj komentarze poniżej. Jeśli ktoś ma pomysł, jak zmienić moją odpowiedź, aby to uwzględnić, zrób to.
źródło
Boolean a = true;
), a następnie ustawić wartość null (a = null;
). Może nie jest to eleganckie ani mądre, ale jest możliwe.Boolean a
; a jest wskaźnikiem do obiektu boolowskiego. Jeślia = null;
nie ustawiłeś swojej wartości logicznej na null, ustawiłeś odniesienie na null. WykonajBoolean a = null; a.booleanValue();
W tym przypadku nigdy nawet nie utworzyłeś obiektu boolowskiego i dlatego zgłosi on wyjątek zerowy. Daj mi znać, jeśli potrzebujesz dalszych instrukcji.Boolean a = true;
, robi jakąś magię, która w rzeczywistości jest interpretowana jakoBoolean a = new Boolean(true);
To, prawdopodobnie nie do końca poprawne ze względu na wydajność, ale musisz zdać sobie sprawę, że wartość logiczna jest nadal przedmiotem.Istnieją trzy szybkie powody:
true
,false
lubnull
xsd:boolean
wartości schematu XML zadeklarowanych wxsd:nillable="true"
List<Boolean>
- nie możesz używaćList<boolean>
źródło
boolean
” (styl umysłu), ponieważ w Oracle zwykle używachar(1) null
się wartości „T” i „F”. Więc może (z np. Adapterem typu Hibernate) być zerowe :)ODPOWIEDŹ NA WŁASNE PYTANIE: Pomyślałem, że warto odpowiedzieć na moje własne pytanie, ponieważ wiele się nauczyłem z odpowiedzi. Ta odpowiedź ma pomóc tym - takim jak ja - którzy nie mają pełnego zrozumienia problemów. Jeśli używam niewłaściwego języka, popraw mnie.
true
ifalse
. To brak wskaźnika do obiektów. Dlatego myślenie, że Boolean ma 3 wartości, jest zasadniczo błędneSkładnia Boolean jest skrócona i ukrywa fakt, że odniesienie wskazuje na Obiekty:
Boolean a = true;
ukrywa fakt, że
true
jest przedmiotem. Inne równoważne zadania to:lub
Skrócona składnia
if (a) ...
różni się od większości innych przypisań i ukrywa fakt, że a może być odniesieniem do obiektu lub prymitywem. Jeśli obiekt jest potrzebny,
null
aby uniknąć NPE. Dla mnie psychologicznie łatwiej to zapamiętać, jeśli istnieje test równości:if (a == true) ...
gdzie możemy zostać poproszeni o przetestowanie wartości null. Tak więc skrócona forma jest bezpieczna tylko wtedy, gdy
a
jest prymitywna.Dla siebie mam teraz zalecenia:
Boolean
z metody, jaka mogłaby byćnull
. Tylko wróćboolean
.Boolean
do zawijania elementów w kontenerach lub argumentów metod, w których wymagane są obiektyźródło
Klasy opakowujące dla prymitywów mogą być używane tam, gdzie wymagane są obiekty, a kolekcje są dobrym przykładem.
Wyobraź sobie, że potrzebujemy jakiegoś sklepu powodu sekwencję
boolean
w sposóbArrayList
, można to zrobić przez boksboolean
wBoolean
.Istnieje kilka słów o tym tutaj
Z dokumentacji:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
źródło
Boolean
wrapper jest przydatny, gdy chcesz sprawdzić, czy wartość została przypisana, czy nie pozatrue
ifalse
. Ma następujące trzy stany:null
Natomiast
boolean
ma tylko dwa stany:Powyższa różnica sprawi, że będzie pomocna w Listach
Boolean
wartości, które mogą miećTrue
,False
lubNull
.źródło
Przypuszczam, że w pewnym przypadku powinieneś mieć mechanizm rozróżniania pola boolowskiego, które już ustawiło wartość lub nie.
źródło
Głównym celem Boolean jest wartość null. Wartość null mówi, że właściwość jest niezdefiniowana , na przykład weź kolumnę dopuszczającą wartość null bazy danych.
Jeśli naprawdę potrzebujesz przekonwertować wszystko z pierwotnych wartości logicznych na logiczne opakowujące, możesz użyć następującego kodu do obsługi starego kodu:
źródło
Wartość ** null ** w opakowaniu typu Boolean ma wiele zastosowań! :)
Na przykład możesz mieć w formularzu pole o nazwie „biuletyn”, które wskazuje, czy użytkownik chce, czy nie chce, aby otrzymywać biuletyn z Twojej witryny. Jeśli użytkownik nie wybierze wartości w tym polu, możesz zaimplementować domyślne zachowanie w tej sytuacji (wysłać? Nie wysyłać ?, pytanie ponownie? Itd.). Oczywiście, not set (or not selected or ** null **), to nie to samo co prawda czy fałsz.
Ale jeśli „nie ustawiono” nie ma zastosowania do Twojego modelu, nie zmieniaj prymitywu logicznego;)
źródło
W ścisłej definicji elementu boolowskiego istnieją tylko dwie wartości. W idealnym świecie to byłaby prawda. W prawdziwym świecie element może brakować lub być nieznany. Zwykle wymaga to wprowadzenia danych przez użytkownika. W systemie opartym na ekranie może to zostać wymuszone przez edycję. W świecie wsadowym korzystającym z bazy danych lub danych wejściowych XML można łatwo brakować elementu.
Tak więc w niedoskonałym świecie, w którym żyjemy, obiekt boolowski jest świetny, ponieważ może reprezentować brakujący lub nieznany stan jako zerowy. W końcu komputery po prostu modelują świat rzeczywisty i powinny uwzględniać wszystkie możliwe stany i obsługiwać je z wyrzucaniem wyjątków (głównie dlatego, że istnieją przypadki użycia, w których zgłoszenie wyjątku byłoby poprawną odpowiedzią).
W moim przypadku obiekt Boolean był idealną odpowiedzią, ponieważ w wejściowym XMLu czasami brakowało elementu i nadal mogłem uzyskać wartość, przypisać ją do wartości Boolean, a następnie sprawdzić wartość null przed próbą użycia z nim testu true lub false .
Tylko moje 2 centy.
źródło
Dla wszystkich dobrych odpowiedzi powyżej, podam konkretny przykład w
HttpSession
klasie serwletów Java . Mam nadzieję, że ten przykład pomoże w wyjaśnieniu niektórych pytań, które nadal możesz mieć.Jeśli chcesz zapisać i pobrać wartości dla sesji, użyj
setAttribute
metody (String, Object) igetAttribute
(String, Object). Tak więc w przypadku wartości logicznej jesteś zmuszony użyć klasy Boolean, jeśli chcesz przechowywać ją w sesji http.Ostatnia linia spowoduje a,
NullPointerException
jeśli wartości atrybutów nie są ustawione. (co jest powodem doprowadziło mnie do tego postu). Tak więc stan logiczny 3 pozostanie, niezależnie od tego, czy wolisz go używać, czy nie.źródło
Najlepszym sposobem byłoby całkowite uniknięcie wartości logicznych, ponieważ każda wartość logiczna implikuje, że w innym miejscu kodu znajduje się instrukcja warunkowa (patrz http://www.antiifcampaign.com/ i to pytanie: Czy możesz napisać dowolny algorytm bez instrukcji if ? ).
Jednak pragmatycznie trzeba od czasu do czasu używać wartości logicznych, ale jak już sam się przekonałeś, radzenie sobie z booleanami jest bardziej podatne na błędy i bardziej uciążliwe. Dlatego sugerowałbym używanie wartości logicznych, gdy tylko jest to możliwe. Wyjątkiem może być starsza baza danych z kolumnami logicznymi dopuszczającymi wartość zerową, chociaż próbowałbym to również ukryć w moim mapowaniu.
źródło
Wartość logiczna może być bardzo pomocna, gdy potrzebujesz trzech stanów. Podobnie jak w testowaniu oprogramowania, jeśli Test zostanie zaliczony, wyślij true, jeśli nie powiodło się, wyślij false, a jeśli przypadek testowy zostanie przerwany, wyślij null, co oznacza, że przypadek testowy nie został wykonany.
źródło