Tôi biết rằng khi tôi đọc câu trả lời cho điều này tôi sẽ thấy rằng tôi đã bỏ qua một cái gì đó đó là dưới mắt tôi. Nhưng tôi đã dành 30 phút cuối cùng để cố gắng tìm ra bản thân mình mà không có kết quả.Chuyển đổi từ null thành int?
Vì vậy, tôi đã viết một chương trình trong Java 6 và phát hiện một số tính năng kỳ lạ (đối với tôi). Để thử và cách ly nó, tôi đã tạo ra hai ví dụ nhỏ. Lần đầu tiên tôi thử phương pháp sau:
private static int foo()
{
return null;
}
và trình biên dịch từ chối: Loại không khớp: không thể chuyển đổi từ null thành int.
Điều này là tốt với tôi và nó tôn trọng ngữ nghĩa Java mà tôi quen thuộc. Sau đó, tôi đã thử các cách sau:
private static Integer foo(int x)
{
if (x < 0)
{
return null;
}
else
{
return new Integer(x);
}
}
private static int bar(int x)
{
Integer y = foo(x);
return y == null ? null : y.intValue();
}
private static void runTest()
{
for (int index = 2; index > -2; index--)
{
System.out.println("bar(" + index + ") = " + bar(index));
}
}
Biên dịch này không có lỗi! Nhưng, theo ý kiến của tôi, cần có một loại chuyển đổi lỗi trong dòng
return y == null ? null : y.intValue();
Nếu tôi chạy chương trình tôi nhận được kết quả như sau:
bar(2) = 2
bar(1) = 1
bar(0) = 0
Exception in thread "main" java.lang.NullPointerException
at Test.bar(Test.java:23)
at Test.runTest(Test.java:30)
at Test.main(Test.java:36)
bạn có thể giải thích hành vi này?
Cập nhật
Cảm ơn bạn rất nhiều vì nhiều câu trả lời làm rõ. Tôi hơi lo lắng vì ví dụ này không tương ứng với trực giác của tôi. Một điều làm tôi băn khoăn là rằng một null đã được chuyển đổi thành một int và tôi đã tự hỏi kết quả sẽ là gì là: 0 như trong C++? Điều đó sẽ rất lạ. Tốt rằng việc chuyển đổi là không thể khi chạy (ngoại lệ con trỏ null).
Quy tắc chung về cách trình biên dịch cố gắng giải quyết các loại trong biểu thức bậc ba là gì? –
+1, điều này có ý nghĩa bây giờ, đối với tôi. Tại sao trình biên dịch không cho phép thử nghiệm đầu tiên, 'int foo() {return null; } ', như trong trường hợp này một lần nữa, nó sẽ tự động' null' thành 'Integer'? hoặc, tôi đoán câu hỏi của tôi nói cách khác là, tại sao nó đã chọn để autobox các lĩnh vực trong hoạt động ternary để 'Integer' và không để chúng như là nguyên thủy? Quyết định đó dựa trên đâu? – c00kiemon5ter
@Oli Tôi không chắc chắn nhưng nó có thể có bahaviour đáng ngạc nhiên, trong đó đây là một ví dụ. Xem [đoạn 15.25] (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.25) của JLS. – Jesper