Boş Boole değerleri ne zaman kullanılmalıdır?


159

Java booleandeğerlerini verir trueve falseBoole sağlarken true, falseve null. My booleanleri s ye dönüştürmeye başladım Boolean. Bu gibi testlerde çökmelere neden olabilir

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

test sırasında

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

anlaşılmaz ve hataya açık görünüyor.

Ne zaman, eğer olursa, Booleans null değerlerle kullanmak yararlı olur ? Hiç değilse, sarılmış nesnenin ana avantajları nelerdir?

GÜNCELLEME: O kadar çok değerli cevap var ki, bazılarını kendi cevabımda özetledim. En iyisi Java'da bir arabulucuyum, bu yüzden yararlı bulduğum şeyleri göstermeye çalıştım. Soru "yanlış ifade" olduğunu unutmayın (Boolean "null değeri olamaz") ama diğerleri aynı yanlış anlama durumunda bıraktım


7
Bazen, başlatılmamış bir durum ve yardımcı Booleandeğişkenin ayarlanmasını istersiniz null.
nhahtdh

2
"Her zaman" onaylamaya cesaret edemediğim için biraz güçlü, ama nullgerçekten 3. durum olarak kullanılıyorsa bir test beklerim.
nhahtdh

6
Booleans'i Booleans'a dönüştürmek için bir nedeniniz var mı? İlkel tipe sadık kalır ve sadece bunu yapmak için iyi bir neden varsa, örneğin referansla bir değişkeni geçmem gerektiğinde sarardım.
jpe

7
: Ayrıca bu kontrol etmek isteyebilirsiniz thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
biziclop

6
Bir "boş değere diye bir şey yoktur yılında Boolean". A Booleanbir nesnedir, a booleanise bir "skaler" dir. Bir Booleanbaşvuru null olarak ayarlanırsa, karşılık gelen Booleannesnenin olmadığı anlamına gelir . Var olmayan bir şeyin içine hiçbir şey yerleştiremezsiniz.
Hot Licks

Yanıtlar:


244

Her zaman booleanyerine kullanın Boolean. Bu, birçok NullPointerExceptions'yi önler ve kodunuzu daha sağlam hale getirir.

Boolean yararlıdır, örneğin

  • booleanları bir koleksiyonda saklamak için (Liste, Harita vb.)
  • nullable boolean'ı temsil etmek için (örneğin, bir veritabanındaki nullable boolean sütunundan geliyor). Boş değer, bu bağlamda "doğru mu yanlış mı bilmiyoruz" anlamına gelebilir.
  • bir yöntemin bağımsız değişken olarak her Nesneye ihtiyacı olduğunda ve bir boolean değeri iletmeniz gerekir. Örneğin, yansıma veya benzeri yöntemler kullanılırken MessageFormat.format().

35
Veritabanındaki boş değer, "FileNotFound"
Karl Johan

31
İkinci merminiz gerçekten bu sorunun doğru cevabının çekirdeğidir bence.
Niels Brinch

3
Boolean için yaşadığım bir başka kullanım da, genel sınıfları genişletirken genel bir tür parametresi olarak - 3. nokta ile yakından ilişkili
Alex

6
Null kavramını "evren bilmiyor" dışında bir anlamla aşırı yüklemek, 3 (veya daha fazla) değerli bir enum kullanmaktan daha zayıftır. Kodu okuma parametrelerini de yönteme daha açık hale getirir.
bluevector

16
Veya # 4: Boolean isSchrodinger‎CatAlive = null;(üzgünüm, direnemedim;)).
Matthieu

58

Neredeyse hiç kullanmıyorum Booleançünkü anlambilimi belirsiz ve belirsizdir. Temel olarak 3 durumlu mantığınız var: doğru, yanlış veya bilinmiyor. Bazen kullanıcıya iki değer arasında bir seçim yaptığınızda ve kullanıcı hiç cevap vermediğinde ve bu bilgiyi gerçekten bilmek istediğinizde kullanmak yararlı olabilir (düşün: NULLable veritabanı sütunu).

Ben dönüştürmek için hiç bir neden görmüyorum booleaniçin Booleanekstra bellek yükü, NPE ihtimalini daha az yazar tanıtır olarak. Tipik olarak BooleanUtils.isTrue()hayatımı biraz daha kolaylaştırmak için garip davranırım Boolean.

Varlığının tek nedeni Boolean, Booleantip koleksiyonlarına sahip olma yeteneğidir (jenerikler booleandiğer tüm ilkellerin yanı sıra izin vermez ).


1
Yine de harici bir kütüphane (Apache müşterileri).
nhahtdh

4
Çok değerli mantık için numaralandırmaların kullanılması tercih edilir. Bu nedenle, veri yapılarında kullanılmak üzere (otomatik) boks değişkenleri için Boolean bırakılmalıdır.
jpe

39
Boolean kullanırken, boş işaretçi istisnalarını önlemek için uygun bir test Boolean.TRUE.equals(myBooleanObject)veya Boolean.FALSE.equals(myBooleanObject).
Christopher Peisert

10
Boole nesnesinin yalnızca iki durumu vardır - trueve false. nullolduğu değil nesnenin bir durum, daha çok nesne bir referans durum.
Hot Licks

2
Apache commons'a "Birisi booleanları değerlendirmeyi berbat edebilir ... bir isTrue()yöntem yapalım ..." gibi bir şey bırakın . Ve yine de, bir şekilde, faydalı ... buradaki en büyük wtf.
corsiKa

33

Vay canına, yeryüzünde ne var? Sadece ben miyim yoksa tüm bu cevaplar yanlış mı yoksa en azından yanıltıcı mı?

Boolean sınıfı, boolean ilkel tipinin etrafındaki bir sarıcıdır. Bu sargının kullanımı, bir nesneyi veya genel nesneyi kabul eden bir yöntemde bir boole iletebilmelidir. Yani vektör.

Boole nesnesinin ASLA değeri null olamaz. Senin Eğer referans bir Boolean null, basitçe senin Boole yaratılmış hiçbir zaman anlamına gelir.

Bunu yararlı bulabilirsiniz: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Boolean.java

Bir boş Boole referansı, yalnızca başka bir boş referansınız olan benzer mantığı tetiklemek için kullanılmalıdır. Üç durum mantığı için kullanmak beceriksizdir.

EDIT: dikkat, bu Boolean a = true;yanıltıcı bir ifadedir. Bu gerçekten daha yakın bir şeye eşittir Boolean a = new Boolean(true); Lütfen burada otomatik kutulamaya bakın: http://en.wikipedia.org/wiki/Boxing_%28computer_science%29#Outoboxing

Belki de bu karışıklığın çoğunun geldiği yerdir.

EDIT2: Lütfen aşağıdaki yorumları okuyun. Herhangi birinin bunu dahil etmek için cevabımı nasıl yeniden yapılandıracağı hakkında bir fikri varsa, lütfen yapın.


2
"Bir Boole hiçbir zaman boş değerli olamaz" ifadesini anlamıyorum. Bir Boolean ( Boolean a = true;) oluşturabilir ve sonra a değerini null ( a = null;) olarak ayarlayabilirim . Zarif veya akıllıca olmayabilir, ancak mümkündür.
peter.murray.rust

7
Yaptığınızda Boolean a; a, bir Boole nesnesinin göstergesidir. Eğer varsa a = null;Sen boş şekilde Boole ayarlamadıysanız bir null için başvuru belirledik. Yap Boolean a = null; a.booleanValue();Bu durumda, hiçbir zaman bir Boolean nesnesi bile yaratmadınız ve bu nedenle bir nullpointerexception oluşturacaktır. Daha fazla talimata ihtiyacınız varsa bana bildirin.
user606723

Ayrıca, bunu yaptığınızda Boolean a = true;, aslında Boolean a = new Boolean(true);performans nedenleriyle Thats muhtemelen doğru değil olarak yorumlanan bir tür sihir yapar , ancak Boolean'ın hala bir nesne olduğunu fark etmelisiniz.
user606723

7
@missingno, Herhangi bir nesneyle ilgilenen tüm kodlar bununla uğraşmak zorunda. Bir nesne başvurusu boş olabilir veya olmayabilir. Bu özel bir durum değildir ve özel bir değerlendirme gerektirmez.
user606723

3
Demek istediğim noktam eksik mississno. Boş referans değerlerini dikkate almamız gerektiğine katılıyorum. Buna asla karşı çıkmadım. Ama bunu HERHANGİ BİR NESNE REFERANSI için yapmalıyız . Boş bir Boole referansı özel durum değildir. Bu nedenle, boş Boole referans değerleri özel bir değerlendirme gerektirmez.
user606723

24

Bunun üç hızlı nedeni vardır:

  • Veritabanı boole değerlerini temsil etmek true,false ya danull
  • XML Şemalarını temsil etmek xsd:boolean değerlerini göstermekxsd:nillable="true"
  • genel türleri kullanabilmek için: List<Boolean>- kullanamazsınızList<boolean>

Açıkça "boolean" yazdım, " boolean" (zihin şekillendirme) değil, çünkü Oracle'da genellikle char(1) null'T' ve 'F' değerleriyle kullanıyorsunuz. Bu yüzden (örneğin, Hazırda Bekleme tipi adaptörle) boş olabilir :)
Grzegorz Grzybek

2
Hangi veritabanı boole için null değerine izin vermez? Sütunu boş bırakılabilir olarak ayarlarsanız, veri türü artık önemli değildir ...
Michal B.

@MichalB. Sybase (ve SQL Server) bit türü infocenter.sybase.com/help/index.jsp?topic=/…
mmmmmm

@Mark - hayır, SQL Server bir boş değer bitine izin veriyor - msdn.microsoft.com/en-us/library/ms177603.aspx
David M

11

SORUNA CEVAP: Cevaplardan çok şey öğrendiğimde kendi sorumu yanıtlamanın yararlı olacağını düşündüm. Bu cevap, benim gibi sorunları tam olarak anlamayanlara yardım etmeyi amaçlamaktadır. Yanlış dil kullanırsam lütfen beni düzeltin.

  • Boş "değer" bir değer değildir ve temelde truevefalse . Nesnelere bir işaretçi olmamasıdır. Bu nedenle Boole'nin 3 değerli olduğunu düşünmek temelde yanlıştır
  • Boolean sözdizimi kısaltılır ve başvurunun Nesneleri işaret ettiği gerçeğini gizler:

    Boolean a = true;

truebir nesne olduğu gerçeğini gizler . Diğer eşdeğer ödevler şunlar olabilir:

Boolean a = Boolean.TRUE;

veya

Boolean a = new Boolean(true);
  • Kısaltılmış sözdizimi

    if (a) ...

diğer ödevlerden farklıdır ve a'nın bir nesne referansı veya ilkel olabileceği gerçeğini gizler. Bir nesne varsa nullNPE'den kaçınmak için test etmek gerekir . Benim için bir eşitlik testi varsa bunu hatırlamak psikolojik olarak daha kolaydır:

if (a == true) ...

burada null değerini test etmemiz istenebilir. Böylece kısaltılmış form ancak ailkel olduğunda güvenlidir .

Kendim için şimdi önerilerim var:

  • 3 değerli mantık için asla null kullanmayın. Sadece doğru ve yanlış kullanın.
  • ASLA Booleanbir yöntemden olduğu gibi dönmeyin null. Sadece geri dön boolean.
  • Yalnızca Booleanöğeleri kaplara veya nesnelerin gerekli olduğu yöntemlere yönelik bağımsız değişkenlere sarmak için kullanın

5
"Yeni Boole (ne olursa olsun)" kullanmayın. Bu, öbek üzerinde yeni bir Boole ortaya koyacaktır. Yine de Boolean değişmezdir. "Boolean.valueOf (whatever)" işlevini kullanın; bu, Boolean.TRUE veya Boolean'a işaret eden bir başvuru oluşturur.
simbo1905

1
Java (12 yıl sonra IMHO) ile ilgili birçok problemden biri, eski dillerin de sahip olduğu boş değerlere yaklaşımın tutarsızlığıdır. Scala'ya bakıldığında, null olabilen veya bir değere sahip olabilen yazılı bir Seçenek kavramına sahiptir (Hiçbiri veya Bazı alt sınıflar). Ardından myOption.getOrElse (defaultValue) öğesini çağırabilirsiniz. Bkz. Scala-lang.org/api/current/scala/Option.html Bu özellik hakkında karmaşık bir şey yok. Yine de yeni JVM dilinde oluşturulduğu için birçok kütüphane bu dili kullanmaktadır. Bu, Java'nın "geçen yüzyıl" meselesinden bazılarını "düzeltir" ama yine de JRE'de çalışan sınıf dosyalarını derler.
simbo1905

10

Temel öğeler için sarıcı sınıfları, nesnelerin gerekli olduğu yerlerde kullanılabilir, koleksiyonlar iyi bir örnektir.

Nedense bir dizi saklamak için ihtiyacınız düşünün booleanbir in ArrayList, bu boks yapılabilir booleaniçindeBoolean .

Bununla ilgili birkaç kelime var var

Belgelerden:

Herhangi bir Java programcısının bildiği gibi, bir koleksiyona int (veya başka bir ilkel değer) koyamazsınız. Koleksiyonlar yalnızca nesne referanslarını tutabilir, bu nedenle ilkel değerleri uygun sarmalayıcı sınıfına (int durumunda Integer olan) kutulamanız gerekir. Nesneyi koleksiyondan çıkardığınızda, koyduğunuz Tamsayı alırsınız; int'e ihtiyacınız varsa, intValue yöntemini kullanarak Tamsayı kutusundan çıkarmanız gerekir. Tüm bu boks ve kutudan çıkarma bir acıdır ve kodunuzu tıkar. Otomatik kutulama ve kutudan çıkarma özelliği, süreci otomatikleştirerek ağrıyı ve dağınıklığı ortadan kaldırır.

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


3

BooleanEğer değer dışında atanmış olup olmadığına istediğinizde sarıcı yararlıdır trueve false. Aşağıdaki üç duruma sahiptir:

  • Doğru
  • Yanlış
  • Tanımlanmayan hangisi null

Halbuki booleansadece iki durumu vardır:

  • Doğru
  • Yanlış

Yukarıdaki fark , veya Booleanolabilen değer listelerinde yardımcı olacaktır .TrueFalseNull


Hayır, boş bir durumu yok, referans bu.
Matsemann

Demek istediğim Bolean tanımlanmış Doğru / Yanlış ve Tanımlanmamış için kullanılabilir.
Ramesh PVK

3

Bazı durumlarda, zaten ayarlanmış veya ayarlanmamış bir Boolean alanını ayırt etmek için bir mekanizmanız olmalıdır.


1

Boolean'ın temel amacı boş değerdir. Boş değer, özelliğin tanımsız olduğunu , örneğin veritabanı null alınabilir sütununu söylüyor .

Gerçekten her şeyi ilkel boole'den sarmalayıcı Boole'ye dönüştürmeniz gerekiyorsa, eski kodu desteklemek için aşağıdakileri kullanabilirsiniz:

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

6
'Temel amaç boş değerdir'. Hayır, Boolean'ın temel amacı, bir boolean'a nesne olarak bir referans iletmektir.
user606723

@ user606723 kabul etti, ben yazarken kafamda veritabanı durumdan bahsediyordum.
JMelnik

1

Boole paketinde ** null ** değeri için birçok kullanım vardır! :)

Örneğin, bir formda, kullanıcının sitenizden bir bülten isteyip istemediğini belirten "bülten" adlı bir alanınız olabilir. Kullanıcı bu alanda bir değer seçmezse, bu duruma varsayılan bir davranış uygulamak isteyebilirsiniz (gönderme? Gönderme?, Tekrar soru ?, vb.). Açıkçası, ayarlanmadı (veya seçilmedi veya ** null **), true veya false ile aynı değil.

Ancak, "ayarlanmadı" modeliniz için geçerli değilse, boole ilkel değerini değiştirmeyin;)


1

Bir boolean öğesinin katı bir tanımında, sadece iki değer vardır. Mükemmel bir dünyada, bu doğru olurdu. Gerçek dünyada, öğe eksik veya bilinmiyor olabilir. Genellikle, bu kullanıcı girdisini içerir. Ekran tabanlı bir sistemde, bir düzenleme ile zorlanabilir. Bir veritabanı veya XML girişi kullanan bir toplu iş dünyasında öğe kolayca eksik olabilir.

Yani, içinde yaşadığımız kusursuz olmayan dünyada, Boolean nesnesi, eksik veya bilinmeyen durumu null olarak temsil edebilmesi açısından harikadır. Sonuçta, bilgisayarlar gerçek dünyayı bir model olarak tüm olası durumları hesaba katmalı ve istisnaları atma ile ele almalıdır (çoğunlukla istisnayı atmanın doğru yanıt olacağı kullanım durumları olduğundan).

Benim durumumda, Boolean nesnesi mükemmel bir yanıttı çünkü giriş XML'si bazen öğe eksikti ve hala bir değer alabilir, bir Boolean'a atayabilir ve daha sonra onunla doğru veya yanlış bir test kullanmaya çalışmadan önce bir boş olup olmadığını kontrol edebilirim. .

Sadece 2 sentim.


1

Yukarıdaki tüm iyi cevaplar için, Java sunucu uygulamasında somut bir örnek vereceğim HttpSession sınıfında . Umarım bu örnek hala sahip olabileceğiniz bazı soruları netleştirmeye yardımcı olur.

Bir oturum için değerleri depolamanız ve almanız gerekiyorsa, setAttribute(String, Object) ve getAttribute(String, Object) yöntemini kullanırsınız. Dolayısıyla, bir boolean değeri için, http oturumunda depolamak istiyorsanız Boolean sınıfını kullanmak zorunda kalırsınız.

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

NullPointerExceptionÖznitelik değerleri ayarlanmadıysa son satır a'ya neden olur . (bu yüzden beni bu göreve götürdü). Bu yüzden 3 mantık durumu, kullanmayı tercih edip etmediğinizi tercih etmek için burada.


0

En iyi yol, boolean'lardan tamamen kaçınmaktır, çünkü her boolean, kodunuzun başka bir yerinde koşullu bir ifadeye sahip olduğunuzu ima eder (bkz. Http://www.antiifcampaign.com/ ve bu soru: if ifadesi olmadan herhangi bir algoritma yazabilir misiniz? ? ).

Bununla birlikte, pragmatik olarak zaman zaman boolean kullanmak zorundasınız, ancak kendiniz zaten bildiğiniz gibi, Booleans ile uğraşmak daha hata eğilimli ve daha hantaldır. Bu yüzden mümkün olan her yerde boolean kullanmanızı öneririm. Eşleme boolean sütunları ile eski bir veritabanı olabilir, ancak eşlememde de gizlemeye çalışacağım.


Booleans'la başa çıkmak, diğer herhangi bir Nesneyle uğraşmak kadar hataya açıktır. BTW, bağlantı genel kullanım için değil, tip kontrolü için IF'lerin çoğalmasına karşıdır. Buna karşılık, bu "tehlikeli" çünkü değişiklikleri daha zor hale getiriyor. Yani IFs per se ile yanlış bir şey yok.
Bay Smith

Sorunun cevabı değil.
Matsemann

@MisterSmith Bir boole bayrağı genellikle bir tür denetleme değişkeni olarak kötüye kullanılır, bu nedenle bağlantı burada da uygulanabilir. Belli bir durumda booleanın doğru araç olup olmadığını düşünmesi gereken bir ipucu olmalıdır. "Boolelardan tamamen kaçının" ifadesi elbette çok radikal ve neredeyse imkansız, bu yüzden ikinci paragrafı ekledim. Ayrıca, şeyleri açıklığa kavuşturmak için "daha fazla hataya eğilimli ve daha hantal" ekledim.
Roland Schneider

0

Üç duruma ihtiyacınız olduğunda Boolean çok yardımcı olabilir. Test geçilirse yazılım testinde olduğu gibi, doğru gönderilirse, başarısız olursa yanlış gönderilir ve test durumu kesilirse, test durumunun yürütülmediğini gösterecek boş değer gönderir.


2
Numaralandırmalar bunun için en iyi olmaz mıydı? Muhtemelen bir müşteri için beklenmedik NullPointerExceptions sağlama yerine, numaralandırmalar açıkça "durumları" tanımlar
Kartik Chugh

Devlet makinelerinde daima boolean yerine enum tercih edin. Yeni bir dördüncü devletin ne zaman iş gereksinimine geldiğini asla bilemezsiniz.
AnupamChugh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.