Tự động unboxing nhu cầu của ternary if-other


23

Đoạn mã này hoạt động tốt: -

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

Nhưng điều này ném ngoại lệ con trỏ null, trong khi Eclipse cảnh báo rằng cần phải tự động hủy hộp thư:

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Tại sao lại như vậy, ai đó có thể hướng dẫn?

Câu trả lời:


22

Các loại biểu thức điều kiện ternary

1 <= 3 ? nullInt : -1

int(JLS chứa một số bảng mô tả loại toán tử điều kiện ternary tùy thuộc vào các loại toán hạng 2 và 3).

Do đó, khi nó cố gắng bỏ hộp nullIntđến một int, a NullPointerExceptionsẽ bị ném.

Để có được hành vi của đoạn mã if-other, bạn cần viết:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Bây giờ loại biểu thức sẽ là Integer, vì vậy không có unboxing sẽ diễn ra.


4
Chỉ cần thêm vào câu trả lời của bạn, đây là các bảng được đề cập: docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

Tôi khá chắc chắn rằng các đối số cho toán tử ternary cần phải cùng loại. Vì bạn sử dụng -1 và một số nullinttrình biên dịch không đổi cố gắng bỏ hộp nullintđể nhận giá trị. Và sau đó autobox nó để lưu trữ trong secondNullbiến.


3

Điều này là do khi hai toán hạng cho toán tử điều kiện ? :là một kiểu nguyên thủy và kiểu tham chiếu được đóng hộp của nó, một chuyển đổi bỏ hộp được thực hiện ( JLS §15.25.2 ):

Loại biểu thức điều kiện số được xác định như sau:

  • ...
  • Nếu một trong các toán hạng thứ hai và thứ ba thuộc loại nguyên thủy T và loại khác là kết quả của việc áp dụng chuyển đổi quyền anh (§5.1.7) cho T, thì loại biểu thức điều kiện là T.

Nói chung, việc thay thế một ifcâu lệnh bằng một ? :biểu thức không phải lúc nào cũng bảo tồn ý nghĩa của mã, bởi vì ? :chính biểu thức đó cần phải có kiểu thời gian biên dịch. Điều đó có nghĩa là khi các loại của hai toán hạng khác nhau, một chuyển đổi phải được thực hiện thành một hoặc cả hai để kết quả có loại thời gian biên dịch nhất quán.


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.