2011-12-15 33 views
9

Tại sao dòng mã sau tạo ra một NullPointerException?NullPointerException trong biểu thức bậc ba với null Dài

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

Tôi hiểu rằng việc hủy hộp đang được thực hiện trên null, nhưng tại sao?

Lưu ý rằng

Long v = (Long) null; 

Không tạo ra ngoại lệ.

+0

Bạn thực hiện lệnh v = ((1 == 2)? Long.MAX_VALUE: (Long) null); điều này luôn luôn sai, vì vậy bạn luôn cố gắng bỏ null thành Long. Điều này có vẻ không được phép và ném ngoại lệ của bạn. – evildead

+0

Tại sao bạn lại có một dòng mã như vậy? Trí tò mò trí tuệ hay là một đoạn trích từ mã sản xuất thực tế? – Paul

+1

@Paul và evildead, trông giống như mã ví dụ để chứng minh thứ tự unboxing. – Steven

Trả lời

9

Vì vậy, có vẻ như bạn chỉ phải vào hộp nếu điều kiện là đúng và sẽ không có quyền nếu điều kiện là sai. Tuy nhiên, biểu thức toán tử bậc ba phải có loại tĩnh tĩnh cụ thể. Vì vậy, chúng tôi có Longlong. JLS nói rằng kết quả sẽ là nguyên thủy (chỉ là tốt - hãy tưởng tượng nếu người vận hành là, ví dụ: + hoặc thậm chí ==). Vì vậy, các nhà điều hành ternary sẽ buộc unboxing, và chỉ sau đó làm nhiệm vụ gây ra một boxing.

Nếu bạn đã thay thế mã bằng tương đương if-else, sau đó bạn muốn chỉ có một bài tập từ long để Long và từ Long để Long, trong đó sẽ không có bất kỳ unboxing và vì vậy hãy chạy tốt.

IIRC, điều này được bao gồm là Bloch & Puzzlers Java của Gafter.

0

Từ JSL

  1. Nếu toán hạng thứ hai và thứ ba có cùng loại (trong đó có thể là loại null), thì đó là kiểu của biểu thức điều kiện.
  2. Nếu một trong hai toán hạng thứ hai và thứ ba thuộc loại boolean và loại kia là loại Boolean, thì loại biểu thức điều kiện là boolean.

Trong tuyên bố sau các loại toán hạng thứ hai là long và thứ ba là Long.

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 

Điều này sẽ hoạt động nếu một biểu thức là đúng.

Long v= 1 == 1 ? Long.MAX_VALUE : (Long) null; 

Hoặc bạn có thể truyền.

Long v= 1 == 2 ? Long.valueOf(Long.MAX_VALUE) : (Long) null; 
+0

Có, tôi biết nó đang làm unboxing, và bạn không thể bỏ trống unbox. Tôi đã hỏi tại sao nó đang cố gắng thực hiện unboxing trong trường hợp này. – jonderry

+0

Điều đó không hoàn toàn chính xác. Anh ta đang cố gắng unbox một đối tượng 'Long' rỗng; dàn diễn viên không phải là vấn đề. Bạn có thể bỏ 'null' vào bất kỳ kiểu đối tượng nào, xem Java Language Spec [phần 5.5] (http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5), dưới "Nếu một diễn viên tham chiếu loại tham chiếu không phải là lỗi thời gian biên dịch, có một số trường hợp:" – Paul

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