Boolean vs boolean trong Java


195

Có các cuộc thảo luận xung quanh Integervs inttrong Java. Giá trị mặc định của cái trước là nulltrong khi cái sau nó 0. Thế còn Booleanvs boolean?

Một biến trong ứng dụng của tôi có thể có 0/ 1giá trị. Tôi muốn sử dụng boolean/ Booleanvà không thích sử dụng int. Tôi có thể sử dụng Boolean/ booleanthay thế không?


2
Vì lý do thiết kế hệ thống, tôi sẽ chọn Boolean vì nó có tùy chọn "Người dùng chưa quyết định", điều này không bằng "đúng", cũng không "sai". Tôi sẽ chỉ sử dụng boolean nguyên thủy trong các trường hợp nếu tôi chắc chắn 100% tùy chọn đúng / sai là đủ. Trong cơ sở dữ liệu, tùy chọn NULL thường có sẵn mà không gặp sự cố (hoặc chỉ cần loại bỏ các hạn chế KHÔNG NULL cho nhu cầu sau này)
CsBalazsHungary

2
Bản sao chính xác của sự khác biệt giữa boolean và Boolean trong Java là gì? (vì GWT không tạo ra sự khác biệt).
Dan Dascalescu

Câu trả lời:


270

Có, bạn có thể sử dụng Boolean/ booleanthay thế.

Cái thứ nhất là Object và cái thứ hai là kiểu nguyên thủy.

  • Đầu tiên, bạn sẽ nhận được nhiều phương thức hữu ích hơn.

  • Thứ hai là giá rẻ khi xem xét chi phí bộ nhớ Thứ hai sẽ giúp bạn tiết kiệm bộ nhớ hơn rất nhiều, vì vậy hãy sử dụng nó

Bây giờ chọn theo cách của bạn.


70
Bạn có thể đã nói điều này là "thứ hai sẽ giúp bạn tiết kiệm bộ nhớ hơn rất nhiều, vì vậy hãy thực hiện nó". Các phương thức hữu ích trên Boolean hầu hết có thể được gọi mà không cần có phiên bản của nó.
DJClayworth

3
Miễn là bạn sử dụng thay vì Boolean.valueOf (giá trị) của Boolean (giá trị) mới, bộ nhớ không phải là vấn đề đáng lo ngại.
Trường hợp Greg

2
cho AsyncTask, bạn chỉ có thể sử dụng Booleanthay vì boolean.
Raptor

98
Cần lưu ý các một Boolean thực sự có 3 tiểu bang ... true, falsenullnơi một boolean có 2 trạng thái logic ( truefalse)
respectTheCode

14
Boolean là trillean :)
Topera

50

Boolean kết thúc kiểu nguyên thủy boolean. Trong JDK 5 trở lên, Oracle (hoặc Sun trước khi Oracle mua chúng) đã giới thiệu autoboxing / unboxing , về cơ bản cho phép bạn làm điều này

boolean result = Boolean.TRUE;

hoặc là

Boolean result = true; 

Mà về cơ bản trình biên dịch làm,

Boolean result = Boolean.valueOf(true);

Vì vậy, đối với câu trả lời của bạn, đó là CÓ.


4
Lưu ý: Bạn không thể luôn luôn gán an toàn Booleancho a boolean. Nếu Booleanlà của bạn nullvà bạn cố gắng gán nó cho a boolean, nó sẽ ném một NullPointerExceptionlúc chạy.
Duncan Luk

Nếu Booleanmột lớp thì tại sao giá trị luôn luôn sai ngay cả khi tôi thay đổi giá trị từ một lớp khác tham chiếu đến cùng một biến Boolean? điểm của vấn đề này Booleanlà gì nếu chúng ta không thể tham chiếu đến từ các lớp đối tượng khác nhau / vượt qua làm đối số?
user924

tìm thấy câu trả lời, chúng ta có thể sử dụng AtomicBooleanvà tham khảo nó từ các lớp khác nhau
user924

35

Tôi hơi mở rộng câu trả lời được cung cấp (từ trước đến nay họ tập trung vào thuật ngữ "riêng" / nhân tạo của họ tập trung vào lập trình một ngôn ngữ cụ thể thay vì quan tâm đến bức tranh lớn hơn đằng sau bối cảnh tạo ra ngôn ngữ lập trình , nói chung là khi mọi thứ như sự cân nhắc về an toàn so với bộ nhớ tạo nên sự khác biệt):

int không phải là boolean

Xem xét

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

với đầu ra

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

Mã Java trên dòng thứ 3 (bar)?1:0minh họa rằng thanh ( boolean ) không thể được chuyển đổi hoàn toàn (được đúc) thành một int . Tôi đưa ra điều này không phải để minh họa các chi tiết triển khai đằng sau JVM, nhưng để chỉ ra rằng về mặt cân nhắc ở mức độ thấp (như kích thước bộ nhớ), người ta phải thích các giá trị hơn mức an toàn kiểu. Đặc biệt là nếu loại an toàn đó không thực sự / được sử dụng đầy đủ như trong các loại boolean nơi kiểm tra được thực hiện dưới dạng

if value \ in {0,1} thì chuyển sang kiểu boolean, nếu không thì ném ngoại lệ.

Tất cả chỉ để nói rằng {0,1} <{-2 ^ 31, .., 2 ^ 31 -1}. Có vẻ như quá mức, phải không? Loại an toàn là thực sự quan trọng trong các loại do người dùng xác định, không phải trong việc đúc nguyên thủy (mặc dù cuối cùng được bao gồm trong loại đầu tiên).

Byte không phải là loại hoặc bit

Lưu ý rằng trong bộ nhớ, biến của bạn trong phạm vi {0,1} sẽ vẫn chiếm ít nhất một byte hoặc một từ (xbits tùy thuộc vào kích thước của thanh ghi) trừ khi được chăm sóc đặc biệt (ví dụ: được đóng gói độc đáo trong bộ nhớ - 8 "boolean" bit thành 1 byte - qua lại).

Bằng cách ưu tiên an toàn loại (như đặt / gói giá trị vào hộp của một loại cụ thể) so với đóng gói giá trị bổ sung (ví dụ: sử dụng dịch chuyển bit hoặc số học), người ta thực sự chọn cách viết ít mã hơn để đạt được nhiều bộ nhớ hơn. (Mặt khác, người ta luôn có thể xác định loại người dùng tùy chỉnh sẽ tạo điều kiện cho tất cả các chuyển đổi không có giá trị hơn Boolean).

từ khóa so với loại

Cuối cùng, câu hỏi của bạn là về việc so sánh từ khóa với loại . Tôi tin rằng điều quan trọng là để giải thích lý do tại sao hoặc làm thế nào một cách chính xác, bạn sẽ có được hiệu suất bằng cách sử dụng / thích các từ khóa ( "đánh dấu" như nguyên thủy ) so với các loại (lớp do người dùng định nghĩa hợp bình thường sử dụng một từ khóa class ) hay nói cách khác

boolean foo = true;

so với

Boolean foo = true;

"Điều" đầu tiên (loại) không thể được mở rộng (phân lớp) và không phải không có lý do. Thuật ngữ Java hiệu quả của các lớp nguyên thủygói có thể được dịch đơn giản thành giá trị nội tuyến (LITITH hoặc hằng được thay thế trực tiếp bởi trình biên dịch bất cứ khi nào có thể suy ra thay thế hoặc nếu không - vẫn dự phòng để bọc giá trị).

Tối ưu hóa đạt được do tầm thường:

"Ít hoạt động đúc thời gian chạy => tốc độ nhanh hơn."

Đó là lý do tại sao khi suy luận kiểu thực tế được thực hiện, nó có thể (vẫn) kết thúc việc khởi tạo lớp gói với tất cả các thông tin loại nếu cần thiết (hoặc chuyển đổi / chuyển thành như vậy).

Vì vậy, sự khác biệt giữa booleanBoolean chính xác là trong CompilationRuntime (hơi xa nhưng gần như là thể hiện so với getClass () ).

Cuối cùng, autoboxing chậm hơn so với nguyên thủy

Lưu ý một thực tế rằng Java có thể làm autoboxing chỉ là một "cú pháp đường". Nó không tăng tốc bất cứ điều gì, chỉ cho phép bạn viết ít mã hơn. Đó là nó. Đúc và gói vào thùng chứa thông tin loại vẫn được thực hiện. Vì lý do hiệu suất, chọn arithologists sẽ luôn bỏ qua việc quản lý thêm việc tạo các thể hiện lớp với thông tin loại để thực hiện an toàn loại. Thiếu an toàn loại là giá bạn phải trả để đạt được hiệu suất. Đối với mã có an toàn loại biểu thức có giá trị boolean (khi bạn viết ít hơn và do đó mã ẩn ) sẽ rất quan trọng, ví dụ như đối với các điều khiển luồng if-then-other.


16

Bạn có thể sử dụng các hằng số Boolean - Boolean.TRUEBoolean.FALSEthay vì 01. Bạn có thể tạo biến của mình theo kiểu booleannếu nguyên thủy là những gì bạn đang theo sau. Bằng cách này, bạn sẽ không phải tạo các Booleanđối tượng mới .


3

Về cơ bản boolean đại diện cho một kiểu dữ liệu nguyên thủy trong đó Boolean đại diện cho một kiểu dữ liệu tham chiếu. câu chuyện này được bắt đầu khi Java muốn trở thành đối tượng hoàn toàn hướng đối tượng, nó được cung cấp khái niệm lớp trình bao bọc để sử dụng kiểu dữ liệu nguyên thủy.

boolean b1;
Boolean b2;

b1b2không giống nhau


3

Một quan sát: (mặc dù điều này có thể được nghĩ về tác dụng phụ)

boolean là một người nguyên thủy có thể nói có hoặc không.

Boolean là một đối tượng (nó có thể đề cập đến có hoặc không hoặc 'không biết' tức là null)


1

Bạn có thể sử dụng Boolean / boolean. Đơn giản là con đường để đi. Nếu bạn không cần api cụ thể (Bộ sưu tập, Luồng, v.v.) và bạn không thấy trước rằng bạn sẽ cần chúng - hãy sử dụng phiên bản nguyên thủy của nó (boolean).

  1. Với nguyên thủy, bạn đảm bảo rằng bạn sẽ không vượt qua các giá trị null.
    Bạn sẽ không rơi vào bẫy như thế này. Đoạn mã dưới đây ném NullPulumException (từ: Booleans, toán tử có điều kiện và 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. Sử dụng Boolean khi bạn cần một đối tượng, ví dụ:

    • Dòng Booleans,
    • Không bắt buộc
    • Bộ sưu tập Booleans
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.