2013-04-26 37 views
15

Đây là một trong những người thuần túy java tôi nghĩ. Gần đây tôi đã có một vấn đề với một phương pháp để thực hiện phân tích cú pháp các giá trị chuỗi tùy chỉnh thành một Boolean. Một nhiệm vụ đơn giản, nhưng đối với một số lý do phương pháp dưới đây đã ném một NullPointerException trong trường hợp null ...NullPointerException từ Boolean

static Boolean parseBoolean(String s) 
{ 
    return ("1".equals(s) ? true : ("0".equals(s) ? false : null)); 
} 

Kiểu trả về cho phương pháp này là Boolean vậy tại sao hoặc làm thế nào có thể một NullPointerException được ném? Từ gỡ lỗi thông qua nó có vẻ là ngoại lệ được ném tại điểm mà câu lệnh điều kiện trong dòng lồng nhau đánh giá null và trả về null cho điều kiện bên trong dòng bên ngoài, nhưng một lần nữa tôi không thể giải thích tại sao.

Cuối cùng tôi đã từ bỏ và viết lại phương pháp này như sau, trong đó hoạt động như mong đợi:

static Boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 
    if ("0".equals(s)) return false; 

    return null; 
} 

Các mã sau đây là một nửa chiều giữa hai và cũng làm việc như mong đợi:

static Boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 

    return "0".equals(s) ? false : null; 
} 
+2

+1 cho một "puzzler" đẹp – NilsH

+0

@NilsH cảm ơn vì +1 và giải pháp! – Robin

Trả lời

13

này cũng hoạt động:

static Boolean parseBoolean(String s) 
{ 
    return ("1".equals(s) ? Boolean.TRUE : ("0".equals(s) ? Boolean.FALSE : null)); 
} 

Vì vậy, lý do bạn nhận được một NPE là do autoboxing vì sử dụng boolean trong điều hành ternary làm cho kết quả của biểu thức được đối xử như một boolean. Và un-boxing của null gây ra một NPE.

+1

+1 Tốt lắm. Không phải cái mà một người ban đầu nghĩ là xem mã. –

+0

Câu trả lời hay @Nils - ma quỷ nhỏ trơn mà một! Tôi đã không nghĩ đến việc sử dụng hằng số 'Boolean'. – Robin

8

My gợi ý? Đừng trở Boolean, trở boolean và ném một ngoại lệ:

static boolean parseBoolean(String s) 
{ 
    if ("1".equals(s)) return true; 
    if ("0".equals(s)) return false; 

    throw new IllegalArgumentException(s + " is not a boolean value."); 
} 

Thông qua một cách tiếp cận như trên sẽ giúp tránh bạn vô tình tham khảo một đối tượng null Boolean.

Xem excellent answer from NilsH để xem lý do tại sao phương thức ban đầu của bạn là ném ngoại lệ.

+1

Tôi đồng ý. Nó tốt hơn để thất bại nhanh hơn chạy vào một NPE sau đó. Một Boolean có sử dụng nó mặc dù, nếu một trong những nhu cầu một giải pháp "tri nhà nước". – NilsH

+0

Đây là trạng thái ba trạng thái, vì vậy tôi thực sự không nên ném ngoại lệ cho các giá trị mong muốn! Cũng không phải là ngoại lệ xử lý đắt hơn sao? – Robin

2

Thú vị nhưng không có câu trả lời cho bạn biết lý do tại sao điều này xảy ra ngay từ đầu.

Điều này có liên quan đến biểu thức bậc ba.

Trình biên dịch giải thích null dưới dạng tham chiếu null đến Boolean, áp dụng các quy tắc autoboxing/unboxing cho Boolean (trên một null) => bạn nhận được NullPointerException khi chạy.

+2

Tôi nghĩ bạn phải đọc lại câu trả lời;) – NilsH

+1

@NilsH có lẽ tại thời điểm viết bài này đã bỏ lỡ phần này của bạn. :) +1 từ tôi. – Eugene

Các vấn đề liên quan