Tôi đã xem qua một số NullPointerException
thực sự kỳ lạ vào một ngày khác gây ra bởi một kiểu truyền bất ngờ trong toán tử bậc ba. Với này (vô dụng gương mẫu) chức năng:NullPointerException thông qua hành vi tự động-boxing của toán tử ternary Java
Integer getNumber() {
return null;
}
Tôi đã chờ đợi hai đoạn mã sau vào được chính xác giống hệt nhau sau khi biên dịch:
Integer number;
if (condition) {
number = getNumber();
} else {
number = 0;
}
vs
Integer number = (condition) ? getNumber() : 0;
.
Hóa ra, nếu condition
là true
, các if
-statement hoạt động tốt, trong khi opration ternary trong đoạn mã thứ hai ném một NullPointerException
. Dường như hoạt động ba năm đã quyết định nhập cả hai lựa chọn vào int
trước khi tự động kết quả trở lại thành một số Integer
!?! Trên thực tế, nếu tôi truyền một cách rõ ràng 0
đến Integer
thì ngoại lệ sẽ biến mất. Nói cách khác:
Integer number = (condition) ? getNumber() : 0;
là không giống nhau như:
Integer number = (condition) ? getNumber() : (Integer) 0;
.
Vì vậy, có vẻ như có sự khác biệt mã byte giữa toán tử bậc ba và số if-else
tương ứng (điều tôi không mong đợi). Điều này đặt ra ba câu hỏi: Tại sao có sự khác biệt? Đây có phải là một lỗi trong việc thực hiện ternary hoặc là có một lý do cho các loại cast? Có một sự khác biệt, là hoạt động bậc ba ít hay nhiều hơn một mức tương đương if
-statement (Tôi biết, sự khác biệt không thể lớn, nhưng vẫn còn)?
Bạn nghiêm túc tin rằng có lỗi trong toán tử bậc ba thay vì hiểu * của bạn về việc sử dụng tài liệu và hạn chế của toán tử? Bạn nghĩ gì về khả năng xảy ra thực tế này? Xem xét việc thay đổi tiêu đề câu hỏi của bạn thành "sự hiểu lầm trong cách toán tử ternary hoạt động". –
Đây là lý do tại sao tôi hỏi câu hỏi tại sao trình biên dịch quyết định rằng getNumber() và 0 cả hai nên đánh giá vào một int nếu tôi gán kết quả cho một số nguyên. Đối với tôi, nó hoàn toàn không có ý nghĩa để bỏ hai đối số đến hạn chế hơn của hai loại TRƯỚC KHI so sánh thay vì loại thực sự yêu cầu SAU so sánh. Tại sao đi qua unboxing và sau đó reboxing getNumber()? –
Nó không tạo ra sự khác biệt nào về bạn và tôi nghĩ * nên * xảy ra. Thay vào đó tất cả những vấn đề là những gì được ghi chép rõ ràng trong JLS. –