บูลีนเทียบกับบูลีนใน Java


197

มีการอภิปรายเกี่ยวIntegerกับ vs intใน Java ค่าเริ่มต้นของอดีตคือในขณะที่หลังมันnull 0แล้วBooleanvs booleanล่ะ

ตัวแปรในแอปพลิเคชันของฉันสามารถมี0/ 1ค่าได้ ผมอยากจะใช้boolean/ และไม่ต้องการที่จะใช้Boolean intฉันสามารถใช้Boolean/ booleanแทนได้หรือไม่?


2
สำหรับเหตุผลในการออกแบบระบบฉันจะเลือกบูลีนเนื่องจากมีตัวเลือก "ผู้ใช้ยังไม่ตัดสินใจ" ซึ่งไม่เท่ากับ "จริง" หรือ "เท็จ" ฉันจะใช้บูลีนดั้งเดิมเฉพาะในกรณีที่ฉันแน่ใจว่าตัวเลือกจริง / เท็จ 100% ก็เพียงพอแล้ว ในฐานข้อมูลตัวเลือก NULL มักจะไม่มีปัญหา (หรือเพียงแค่ลบข้อ จำกัด NULL ตามความต้องการในภายหลัง)
CsBalazsHungary

2
ซ้ำกันแน่นอนของความแตกต่างระหว่างบูลีนและบูลีนใน Java คืออะไร? (เพราะ GWT ไม่ได้สร้างความแตกต่าง)
Dan Dascalescu

คำตอบ:


272

ใช่คุณสามารถใช้Boolean/ booleanแทน

คนแรกคือวัตถุและคนที่สองเป็นประเภทดั้งเดิม

  • ในครั้งแรกคุณจะได้รับวิธีการเพิ่มเติมซึ่งจะเป็นประโยชน์

  • อันที่สองราคาถูกเมื่อพิจารณาค่าใช้จ่ายหน่วยความจำ ที่สองจะช่วยให้คุณประหยัดหน่วยความจำมากขึ้นไปเลย

ตอนนี้เลือกวิธีของคุณ


70
คุณอาจใช้ประโยคนี้เป็น "วินาทีจะช่วยให้คุณประหยัดความจำได้มากขึ้นไปเลย" วิธีการที่มีประโยชน์ในบูลีนส่วนใหญ่สามารถเรียกใช้โดยไม่ต้องมีอินสแตนซ์ของมัน
DJClayworth

3
ตราบใดที่คุณใช้ Boolean.valueOf (ค่า) แทน Boolean ใหม่ (ค่า) แทนหน่วยความจำไม่ควรกังวล
Greg Case

2
สำหรับAsyncTaskคุณสามารถใช้Booleanแทนbooleanได้เท่านั้น
Raptor

99
มันควรจะตั้งข้อสังเกตบูลีนจริงมี 3 รัฐ ... true, falseและnullที่บูลมีตรรกะ 2 รัฐ ( trueและfalse)
respectTheCode

14
บูลีนเป็น trillean :)
Topera

50

Boolean ล้อมรอบประเภทบูลีนดั้งเดิม ใน JDK 5 ขึ้นไป Oracle (หรือ Sun ก่อนที่จะซื้อ Oracle) เปิดตัวautoboxing / unboxingซึ่งช่วยให้คุณสามารถทำได้

boolean result = Boolean.TRUE;

หรือ

Boolean result = true; 

ซึ่งโดยพื้นฐานแล้วคอมไพเลอร์ทำ

Boolean result = Boolean.valueOf(true);

ดังนั้นสำหรับคำตอบของคุณก็คือใช่


4
หมายเหตุ: คุณไม่สามารถเสมอได้อย่างปลอดภัยกำหนดให้เป็นBoolean booleanหากคุณBooleanเป็นnullและคุณพยายามที่จะกำหนดให้กับbooleanมันก็จะโยนNullPointerExceptionที่รันไทม์
Duncan Luk

ถ้าBooleanคลาสแล้วทำไมค่าจึงเป็นเท็จเสมอแม้ว่าฉันจะเปลี่ยนค่าจากคลาสอื่นที่อ้างอิงถึงตัวแปรบูลีนเดียวกัน สิ่งที่เป็นจุดของเรื่องนี้Booleanแล้วถ้าเราไม่สามารถที่จะอ้างอิงจากชั้นเรียนเช่นแตกต่างกัน / เป็นอาร์กิวเมนต์ผ่าน?
user924

พบคำตอบเราสามารถใช้AtomicBooleanและอ้างอิงจากคลาสที่ต่างกัน
user924

35

ฉันเป็นคำตอบที่เพิ่มขึ้นเล็กน้อย (เนื่องจากจนถึงตอนนี้พวกเขามุ่งเน้นไปที่คำศัพท์ "ของตัวเอง" / ประดิษฐ์โดยมุ่งเน้นที่การเขียนโปรแกรมภาษาเฉพาะแทนที่จะดูแลภาพใหญ่กว่าเบื้องหลังการสร้างภาษาโปรแกรมโดยทั่วไปคือเมื่อสิ่งต่าง ๆ เช่นข้อควรพิจารณาเกี่ยวกับประเภทความปลอดภัยและความจำทำให้เกิดความแตกต่าง):

int ไม่ใช่บูลีน

พิจารณา

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

กับเอาท์พุท

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

รหัส Java ในบรรทัดที่ 3 (bar)?1:0แสดงให้เห็นว่าบาร์ ( บูล ) ไม่สามารถแปลงโดยปริยาย (หล่อ) เป็นint ฉันกำลังนำเรื่องนี้ขึ้นมาเพื่อไม่แสดงให้เห็นถึงรายละเอียดของการดำเนินการที่อยู่เบื้องหลัง JVM แต่เพื่อชี้ให้เห็นว่าในแง่ของการพิจารณาในระดับต่ำ (เป็นขนาดหน่วยความจำ) หนึ่งจะต้องชอบค่ามากกว่าความปลอดภัย โดยเฉพาะอย่างยิ่งถ้าความปลอดภัยประเภทนั้นไม่ได้ใช้อย่างแท้จริง / อย่างเต็มที่ในประเภทบูลีนซึ่งการตรวจสอบจะทำในรูปแบบของ

ถ้า value \ in {0,1} แล้วส่งไปยังประเภทบูลีนมิฉะนั้นจะเกิดข้อยกเว้น

ทั้งหมดเพียงระบุว่า {0,1} <{-2 ^ 31, .. , 2 ^ 31 -1} ดูเหมือนว่า overkill ใช่ไหม? ความปลอดภัยของประเภทนั้นมีความสำคัญอย่างแท้จริงในประเภทที่ผู้ใช้กำหนดไม่ใช่การคัดเลือกแบบดั้งเดิม (แม้ว่าจะรวมอยู่ในครั้งแรก)

ไบต์ไม่ใช่ชนิดหรือบิต

โปรดทราบว่าในหน่วยความจำตัวแปรของคุณจากช่วง {0,1} จะยังคงครอบครองอย่างน้อยหนึ่งไบต์หรือคำ (xbits ขึ้นอยู่กับขนาดของการลงทะเบียน) เว้นแต่ได้รับการดูแลเป็นพิเศษ (เช่นบรรจุไว้ในหน่วยความจำ - 8 "boolean" บิตเป็น 1 ไบต์ - ไปมา)

โดยการเลือกประเภทความปลอดภัย (เช่นในการใส่ / ห่อค่าลงในกล่องชนิดพิเศษ) บนการบรรจุแบบพิเศษ (เช่นการใช้บิตกะหรือเลขคณิต) ผู้ใช้เลือกที่จะเขียนโค้ดน้อยลงเพื่อเพิ่มหน่วยความจำมากขึ้น (ในอีกด้านหนึ่งสามารถกำหนดประเภทผู้ใช้ที่กำหนดเองซึ่งจะช่วยให้การแปลงทั้งหมดไม่คุ้มค่ากว่าบูลีน)

คำหลักกับประเภท

สุดท้ายคำถามของคุณเกี่ยวกับการเปรียบเทียบคำหลักเมื่อเทียบกับประเภท ผมเชื่อว่ามันเป็นสิ่งสำคัญที่จะอธิบายว่าทำไมหรือวิธีการว่าคุณจะได้รับประสิทธิภาพการทำงานโดยใช้ / เลือกคำหลัก ( "เครื่องหมาย" เป็นดั้งเดิม ) มากกว่าประเภท (เรียนที่ผู้ใช้กำหนดปกติคอมโพสิตใช้คำอีกชั้น ) หรืออีกนัยหนึ่ง

boolean foo = true;

เมื่อเทียบกับ

Boolean foo = true;

"สิ่ง" แรก (ประเภท) ไม่สามารถขยายได้ (คลาสย่อย) และไม่ได้โดยไม่มีเหตุผล คำศัพท์ Java อย่างมีประสิทธิภาพของคลาสดั้งเดิมและ คลาสการตัดคำสามารถแปลเป็นค่าอินไลน์ (ตัวย่อหรือค่าคงที่ที่ถูกแทนที่โดยตรงโดยคอมไพเลอร์เมื่อใดก็ตามที่เป็นไปได้ที่จะอนุมานการแทนค่าหรือถ้าไม่ -

การเพิ่มประสิทธิภาพสามารถทำได้เนื่องจากเรื่องเล็กน้อย:

"การดำเนินการแคสต์ Runtime น้อยลง => ความเร็วมากขึ้น"

นั่นคือเหตุผลที่เมื่อทำการอนุมานประเภทจริงมันอาจ (ยัง) สิ้นสุดในการอินสแตนซ์ของคลาสการตัดคำด้วยข้อมูลชนิดทั้งหมดหากจำเป็น

ดังนั้นความแตกต่างระหว่างบูลีนและบูลีนจึงอยู่ในการรวบรวมและรันไทม์ (ค่อนข้างไกล แต่เกือบจะเหมือนกับinstanceofกับgetClass () )

ในที่สุดการ Autoboxing ช้ากว่าระบบพื้นฐาน

สังเกตความจริงที่ว่า Java สามารถทำการautoboxingเป็นเพียง "น้ำตาลทราย" มันไม่ได้เพิ่มความเร็วอะไรเลยเพียงแค่ให้คุณเขียนโค้ดน้อยลง แค่นั้นแหละ. ยังคงดำเนินการส่งและตัดคำในคอนเทนเนอร์ข้อมูลชนิด สำหรับเหตุผลด้านประสิทธิภาพให้เลือกเครื่องคิดเลขซึ่งจะข้ามการทำความสะอาดพิเศษของการสร้างอินสแตนซ์ของชั้นเรียนพร้อมกับข้อมูลประเภทเพื่อใช้ความปลอดภัยของประเภท การขาดความปลอดภัยประเภทคือราคาที่คุณจ่ายเพื่อให้ได้ประสิทธิภาพ สำหรับรหัสที่มีความปลอดภัยประเภทนิพจน์ที่มีค่าบูลีน (เมื่อคุณเขียนน้อยลงและรหัสโดยนัย ) จะมีความสำคัญเช่นสำหรับ if-then-else flow control


16

คุณสามารถใช้ค่าคงที่แบบบูล - Boolean.TRUEและBoolean.FALSEแทนและ0 1คุณสามารถสร้างตัวแปรของคุณเป็นประเภทbooleanถ้าดั้งเดิมคือสิ่งที่คุณหลังจาก วิธีนี้คุณจะไม่ต้องสร้างBooleanวัตถุ ใหม่


4

การสังเกตหนึ่ง: (แม้ว่าสิ่งนี้สามารถนึกถึงผลข้างเคียง)

บูลีนเป็นแบบดั้งเดิมอาจบอกว่าใช่หรือไม่

บูลีนเป็นวัตถุ (สามารถอ้างอิงได้ทั้งใช่หรือไม่ใช่หรือ 'ไม่รู้' เช่นค่าว่าง)


3

โดยทั่วไปบูลีนเป็นตัวแทนของชนิดข้อมูลดั้งเดิมที่บูลีนเป็นตัวแทนของชนิดข้อมูลอ้างอิง เรื่องนี้เริ่มต้นขึ้นเมื่อ Java ต้องการที่จะกลายเป็น object ล้วนๆโดยมีแนวคิดคลาส wrapper เป็นหลักเพื่อใช้ชนิดข้อมูลดั้งเดิม

boolean b1;
Boolean b2;

b1และb2ไม่เหมือนกัน


1

คุณสามารถใช้บูลีน / บูลีน ความเรียบง่ายเป็นวิธีที่จะไป หากคุณไม่ต้องการ API ที่เฉพาะเจาะจง (คอลเลกชัน, สตรีม, ฯลฯ ) และคุณไม่ได้คาดหวังว่าคุณจะต้องการมัน - ใช้เวอร์ชันดั้งเดิมของมัน (บูลีน)

  1. ด้วยพื้นฐานคุณรับประกันได้ว่าคุณจะไม่ผ่านค่า null
    คุณจะไม่ตกหลุมพรางเช่นนี้ รหัสด้านล่างจะแสดง NullPointerException (จาก: Booleans, โอเปอเรเตอร์ที่มีเงื่อนไขและ 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. ใช้บูลีนเมื่อคุณต้องการวัตถุเช่น:

    • กระแสของ Booleans
    • ไม่จำเป็น
    • คอลเล็กชันของ Booleans
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.