Boolean vs boolean w Javie

195

Trwają dyskusje wokół Integervs intw Javie. Domyślną wartością tego pierwszego jest, nullpodczas gdy w drugiej 0. Co powiesz na Booleanvsboolean ?

Zmienna w mojej aplikacji może mieć 0/ 1wartości. Chciałbym użyć boolean/ Booleani wolę nie używać int. Czy mogę użyć Boolean/ booleanzamiast?

Neel
źródło
2
Ze względów projektowych systemu wybrałbym wartość logiczną, ponieważ ma opcję „Użytkownik jeszcze nie zdecydował”, co nie jest równoznaczne z „prawdą” ani „fałszem”. Użyłbym prymitywów boolowskich tylko w przypadkach, gdy jestem w 100% pewien, że wystarczą opcje prawda / fałsz. W bazie danych opcja NULL jest zwykle dostępna bez problemu (lub po prostu usuwając ograniczenia NOT NULL na późniejsze żądanie)
CsBalazsHungary
2
Dokładna kopia Jaka jest różnica między wartością logiczną a logiczną w Javie? (ponieważ GWT nie robi różnicy).
Dan Dascalescu

Odpowiedzi:

270

Tak , możesz użyć Boolean/ booleanzamiast.

Pierwszy to Object, a drugi to prymitywny typ.

  • Za pierwszym razem dostaniesz więcej metod, które będą przydatne.

  • Drugi jest tani, biorąc pod uwagę koszt pamięci . Drugi pozwoli ci zaoszczędzić dużo więcej pamięci, więc idź

Teraz wybierz swoją drogę.

Jigar Joshi
źródło
70
Mógłbyś to sformułować jako „sekunda pozwoli ci zaoszczędzić dużo więcej pamięci, więc idź na całość”. Przydatne metody Boolean można w większości wywoływać bez ich wystąpienia.
DJClayworth,
3
Tak długo, jak użyjesz Boolean.valueOf (wartość) nowego Boolean (wartość), pamięć nie powinna stanowić problemu.
Greg Case
2
bo AsyncTaskmożesz użyć tylko Booleanzamiast boolean.
Raptor
98
Należy zauważyć, że boolean faktycznie ma 3 stany ... true, falsea nullgdzie boolean ma logiczne 2 stany ( truei false)
szacunek TheCode
14
Boolean jest trilleanem :)
Topera
50

Boolean otacza typ pierwotny boolowski. W JDK 5 i wyższych Oracle (lub Sun, zanim Oracle je kupił) wprowadziło autoboxing / unboxing , co w zasadzie pozwala ci to zrobić

boolean result = Boolean.TRUE;

lub

Boolean result = true; 

Który zasadniczo robi kompilator,

Boolean result = Boolean.valueOf(true);

Tak więc, dla twojej odpowiedzi, to TAK.

Buhake Sindi
źródło
4
Uwaga: Nie zawsze możesz bezpiecznie przypisać a Booleando boolean. Jeśli twoje Booleanznaczy nulli spróbować przypisać go do boolean, będzie rzucać NullPointerExceptionw czasie wykonywania.
Duncan Luk
jeśli Booleanklasa, to dlaczego wartość zawsze jest fałszywa, nawet jeśli zmieniłem wartość z innej klasy, odwołując się do tej samej zmiennej boolowskiej? jaki jest tego sens, Booleanjeśli nie możemy odwoływać się do różnych klas instancji / przekazać jako argument?
user924
znaleźliśmy odpowiedź, możemy jej użyć AtomicBooleani odnieść się do niej z klas różnic
user924
35

Nieco rozszerzam dostarczone odpowiedzi (ponieważ jak dotąd koncentrują się na swojej „własnej” / sztucznej terminologii, koncentrując się na programowaniu określonego języka zamiast zajmować się szerszym obrazem za kulisami tworzenia języków programowania , tj. Kiedy rzeczy różnica między bezpieczeństwem typu a pamięcią):

int nie jest wartością logiczną

Rozważać

    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);

z wyjściem

    Bar is true
    Bar is 1
    Baz is 1
    Baz is true

Kod Java w 3. linii (bar)?1:0pokazuje, że bar ( boolean ) nie może być niejawnie przekonwertowany (rzutowany) na int . Podnoszę to, aby nie zilustrować szczegółów implementacji JVM, ale wskazać, że biorąc pod uwagę względy niskiego poziomu (jako rozmiar pamięci), należy wybierać wartości nad bezpieczeństwem typu. Zwłaszcza jeśli tego typu bezpieczeństwo nie jest w pełni / w pełni stosowane, jak w typach boolowskich, w których kontrole są przeprowadzane w formie

jeśli wartość \ w {0,1}, to rzutuj na typ boolowski, w przeciwnym razie wyrzuć wyjątek.

Wszystko po to, aby stwierdzić, że {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Wydaje się, że to przesada, prawda? Bezpieczeństwo typów jest naprawdę ważne w typach zdefiniowanych przez użytkownika, a nie w niejawnym rzutowaniu prymitywów (chociaż ostatnie są uwzględnione w pierwszym).

Bajty nie są typami ani bitami

Zauważ, że w pamięci twoja zmienna z zakresu {0,1} nadal będzie zajmować co najmniej bajt lub słowo (xbity w zależności od wielkości rejestru), chyba że specjalnie się o to zatroszczysz (np. Ładnie zapakowany w pamięć - 8 „boolean” bitów na 1 bajt - tam iz powrotem).

Preferując bezpieczeństwo typu (jak wstawianie / zawijanie wartości do pudełka określonego typu) niż pakowanie dodatkowej wartości (np. Przy użyciu przesunięcia bitów lub arytmetyki), efektywnie wybiera się pisanie mniejszego kodu niż uzyskanie większej pamięci. (Z drugiej strony zawsze można zdefiniować niestandardowy typ użytkownika, który ułatwi całą konwersję nie wartą wartości logicznej).

słowo kluczowe a typ

Wreszcie, twoje pytanie dotyczy porównania słowa kluczowego z typem . Uważam, że ważne jest wyjaśnienie, dlaczego lub w jaki sposób uzyskasz skuteczność, używając / preferując słowa kluczowe („oznaczone” jako prymitywne ) nad typami (zwykłe złożone klasy definiowane przez użytkownika za pomocą innej klasy słów kluczowych ) lub innymi słowy

boolean foo = true;

vs.

Boolean foo = true;

Pierwszej „rzeczy” (typu) nie można rozszerzyć (podklasować) i nie bez powodu. Skutecznie terminologię Java prymitywnych i zawijających klas można po prostu przetłumaczyć na wartość wbudowaną (LITERAL lub stałą, która jest bezpośrednio zastępowana przez kompilator, ilekroć możliwe jest wnioskowanie o podstawieniu lub, jeśli nie, - powrót do zawijania wartości).

Optymalizację osiąga się dzięki trywialnym:

„Mniej operacji rzutowania w czasie wykonywania => większa prędkość.”

Dlatego po dokonaniu faktycznego wnioskowania typu może (nadal) skończyć się wystąpieniem instancji klasy zawijania ze wszystkimi informacjami o typie, jeśli to konieczne (lub konwersją / rzutowaniem na takie).

Tak więc różnica między wartością logiczną a logiczną jest dokładnie w kompilacji i środowisku wykonawczym (nieco daleko, ale prawie jak instancja vs. getClass () ).

Wreszcie, autoboksowanie jest wolniejsze niż prymitywy

Zauważ, że Java może wykonywać autoboxing to po prostu „cukier składniowy”. Nic nie przyspiesza, pozwala tylko napisać mniej kodu. Otóż ​​to. Nadal wykonuje się rzutowanie i zawijanie do kontenera informacji o typie. Ze względu na wydajność wybierz arytmetykę, która zawsze pominie dodatkowe czynności porządkowe podczas tworzenia instancji klasy z informacjami o typie w celu wdrożenia bezpieczeństwa typu. Brak bezpieczeństwa typu to cena, którą płacisz za uzyskanie wydajności. W przypadku kodu z wyrażeniami o wartości logicznej bezpieczeństwo typu (gdy piszesz mniej, a tym samym niejawny kod) ma kluczowe znaczenie, np. W przypadku kontroli przepływu „jeśli-to-inaczej”.

Yauhen Yakimovich
źródło
16

Możesz użyć stałych logicznych - Boolean.TRUEi Boolean.FALSEzamiast 0i 1. Możesz utworzyć zmienną według typu, booleanjeśli szukasz pierwotnego elementu . W ten sposób nie będziesz musiał tworzyć nowych Booleanobiektów.

CoolBeans
źródło
3

Zasadniczo wartość logiczna reprezentuje pierwotny typ danych, gdzie wartość logiczna reprezentuje typ danych odniesienia. ta historia zaczyna się, gdy Java chce się całkowicie zorientować obiektowo, dlatego oferuje koncepcję klasy opakowania, aby móc korzystać z pierwotnego typu danych.

boolean b1;
Boolean b2;

b1i b2nie są takie same.

Sachin Jadhav
źródło
3

Jedna obserwacja: (choć można to pomyśleć o skutkach ubocznych)

boolean będący prymitywem może powiedzieć „tak” lub „nie”.

Boolean jest obiektem (może odnosić się do tak lub nie lub „nie wiem”, tj. Null)

Sudip Bhandari
źródło
1

Możesz użyć Boolean / boolean. Prostota to droga. Jeśli nie potrzebujesz konkretnego interfejsu API (kolekcje, strumienie itp.) I nie przewidujesz, że będziesz go potrzebować - użyj jego prymitywnej wersji (boolean).

  1. Z prymitywami gwarantujesz, że nie przekażesz wartości null.
    Nie wpadniesz w takie pułapki. Poniższy kod zgłasza wyjątek NullPointerException (z: booleany, operatory warunkowe i autoboxing ):

    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. Użyj Boolean, gdy potrzebujesz obiektu, np .:

    • Strumień booleanów,
    • Opcjonalny
    • Kolekcje boolejczyków
Witold Kaczurba
źródło