Đoạn mã sau ném NullPointerException
:
int num = Integer.getInteger("123");
Trình biên dịch của tôi có đang gọi getInteger
null vì nó tĩnh không? Điều đó không có ý nghĩa gì!
Chuyện gì đang xảy ra vậy?
Đoạn mã sau ném NullPointerException
:
int num = Integer.getInteger("123");
Trình biên dịch của tôi có đang gọi getInteger
null vì nó tĩnh không? Điều đó không có ý nghĩa gì!
Chuyện gì đang xảy ra vậy?
Câu trả lời:
Có hai vấn đề đang diễn ra ở đây:
Integer getInteger(String)
không làm những gì bạn nghĩ nó làm
null
trong trường hợp nàyInteger
đến int
nguyên nhân tự động unboxing
Integer
là null
, NullPointerException
được némĐể phân tích (String) "123"
để (int) 123
, bạn có thể sử dụng ví dụ int Integer.parseInt(String)
.
Integer
Tham chiếu APIInteger.getInteger
Đây là những gì tài liệu nói về những gì phương pháp này thực hiện:
public static Integer getInteger(String nm)
: Xác định giá trị nguyên của thuộc tính hệ thống với tên được chỉ định. Nếu không có thuộc tính nào có tên được chỉ định, nếu tên được chỉ định trống hoặcnull
hoặc nếu thuộc tính không có định dạng số chính xác, thìnull
được trả về.
Nói cách khác, phương thức này không liên quan gì đến việc phân tích cú pháp a String
thành một int/Integer
giá trị, mà đúng hơn, nó liên quan đến System.getProperty
phương thức.
Phải thừa nhận rằng đây có thể là một điều khá bất ngờ. Thật không may khi thư viện có những điều bất ngờ như thế này, nhưng nó dạy cho bạn một bài học quý giá: hãy luôn tra cứu tài liệu để xác nhận những gì một phương pháp thực hiện.
Về cơ bản, một biến thể của vấn đề này đã được giới thiệu trong Return of the Puzzlers: Schlock and Awe (TS-5186) , Josh Bloch và Neal Gafter 2009 Technical Session trình bày. Đây là slide kết luận:
Đạo đức
- Phương pháp kỳ lạ và khủng khiếp ẩn trong thư viện
- Một số có tên nghe vô thưởng vô phạt
- Nếu mã của bạn hoạt động sai
- Đảm bảo rằng bạn đang gọi đúng phương thức
- Đọc tài liệu thư viện
- Đối với nhà thiết kế API
- Đừng vi phạm nguyên tắc ít ngạc nhiên nhất
- Không vi phạm phân cấp trừu tượng
- Không sử dụng các tên tương tự cho các hành vi cực kỳ khác nhau
Để hoàn thiện, cũng có những phương pháp này tương tự như Integer.getInteger
:
Tất nhiên, vấn đề khác là làm thế nào để NullPointerException
ném. Để tập trung vào vấn đề này, chúng ta có thể đơn giản hóa đoạn mã như sau:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Đây là trích dẫn từ Phiên bản Java thứ 2 hiệu quả, Mục 49: Ưu tiên các kiểu nguyên thủy hơn các kiểu nguyên thủy đóng hộp:
Tóm lại, ưu tiên sử dụng các nguyên thủy cho nguyên thủy đóng hộp bất cứ khi nào bạn có lựa chọn. Các loại nguyên thủy đơn giản hơn và nhanh hơn. Nếu bạn phải sử dụng nguyên liệu đóng hộp, hãy cẩn thận! Tính năng tự động đóng hộp làm giảm tính dài dòng, nhưng không nguy hiểm, của việc sử dụng các nguyên mẫu đóng hộp. Khi chương trình của bạn so sánh hai nguyên thủy đóng hộp với
==
toán tử, nó sẽ thực hiện một so sánh danh tính, điều này gần như chắc chắn không phải là điều bạn muốn. Khi chương trình của bạn thực hiện các phép tính kiểu hỗn hợp liên quan đến các nguyên thủy được đóng hộp và không được đóng hộp, nó sẽ thực hiện việc mở hộp và khi chương trình của bạn thực hiện việc mở hộp, nó có thể némNullPointerException
. Cuối cùng, khi chương trình của bạn đóng hộp các giá trị nguyên thủy, nó có thể dẫn đến việc tạo đối tượng tốn kém và không cần thiết.
Có những nơi bạn không có lựa chọn nào khác ngoài việc sử dụng nguyên liệu đóng hộp, ví dụ như thuốc chung, nhưng nếu không, bạn nên nghiêm túc xem xét nếu quyết định sử dụng nguyên liệu đóng hộp là chính đáng.
Integer.getInteger(s)
gần tương đương với Integer.parseInt(System.getProperty(s))
? Tôi nghĩ tôi thích cái thứ hai hơn, mặc dù nó dài dòng hơn, vì nó làm nổi bật thực tế là bạn đang lấy thông tin từ các thuộc tính hệ thống.
Integer.decode
thay vì Integer.parseInt
tìm kiếm đầu 0x
hoặc 0
để phân tích cú pháp số dưới dạng thập lục phân hoặc bát phân, tương ứng.
NullPointerException
? : programmers.stackexchange.com/questions/158908/…
Từ http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Xác định giá trị số nguyên của thuộc tính hệ thống với tên được chỉ định.'
Bạn muốn điều này:
Integer.parseInt("123")
Vui lòng kiểm tra tài liệu của phương thức getInteger () . Trong phương thức này, String
tham số là thuộc tính hệ thống xác định giá trị nguyên của thuộc tính hệ thống với tên được chỉ định. "123" không phải là tên của bất kỳ thuộc tính hệ thống nào, như đã thảo luận ở đây . Nếu bạn muốn chuyển đổi Chuỗi này thành int
, hãy sử dụng phương thức dưới dạng
int num = Integer.parseInt("123")
.