Hôm nay tôi sẽ chỉ cho bạn các kỹ thuật đơn giản về cách tránh NullPointerException trong ứng dụng của bạn. Chúng rất dễ làm theo nhưng cải thiện đáng kể độ tin cậy và chất lượng mã của bạn. Hơn nữa, theo kinh nghiệm của tôi, mẹo đầu tiên sẽ có tác động rõ rệt đến chất lượng mã của bạn. Nếu bạn biết bất kỳ thủ thuật lập trình Java nào khác, vui lòng chia sẻ chúng trong phần bình luận.
Sử dụng
Có rất nhiều thư viện nguồn mở đảm nhận công việc kiểm tra Cố gắng không trả về
Đây là một mẹo lập trình Java hay khác mà Joshua Bloch mô tả trong cuốn sách Java: Lập trình hiệu quả của mình. Khi trả về các bộ sưu tập hoặc mảng trống, hãy đảm bảo rằng việc gọi các phương thức cơ bản như
Gọi các phương thức bằng() và bằngIgnoreCase() trên một chuỗi ký tự đã biết thay vì một đối tượng không xác định
Luôn gọi một phương thứcequals()
trên một chuỗi đã biết mà bạn biết là không phải vậy null
. Phương thức này equals()
có tính đối xứng, nghĩa là gọi a.equals(b)
và b.equals(a)
sẽ cho kết quả như nhau (nếu a
và b
không null
), và vì lý do này mà nhiều lập trình viên không chú ý đến đối tượng nào được gọi equals()
, y a
hay y b
. Một trong những tác dụng phụ của việc này là NullPointerException nếu phương thức này được gọi trên null
.
Object unknownObject = null;
//плохой способ - может вызвать NullPointerException
if(unknownObject.equals("knownObject")){
System.err.println("This may result in NullPointerException if unknownObject is null");
}
//правильный способ - исключение NullPointerException не возникнет, даже если unknownObject null
if("knownObject".equals(unknownObject)){
System.err.println("better coding avoided NullPointerException");
}
Đây là mẹo đơn giản nhất để tránh NullPointerException, nhưng chỉ riêng nó đã tạo nên sự cải thiện lớn vì phương pháp này equals()
có ở khắp mọi nơi.
Chọn valueOf() thay vì toString() trong trường hợp cả hai đều tạo ra cùng một kết quả
Vì việc gọitoString()
một tham chiếu có giá trị null
sẽ ném ra một ngoại lệ NullPointerException, nên tốt hơn nên sử dụng lệnh gọi valueOf()
khi chúng ta có thể nhận được kết quả tương tự, vì việc gọi valueOf()
từ null
trả về null
. Điều này đặc biệt đúng đối với các lớp bao bọc như Integer
, Float
hoặc Double
.BigDecimal
BigDecimal bd = getPrice();
System.out.println(String.valueOf(bd)); //не выбрасывает NPE
System.out.println(bd.toString()); //выбрасывает "Exception in thread "main" java.lang.NullPointerException"
Hãy sử dụng những lời khuyên này khi bạn không chắc chắn liệu một vật thể có thể tồn tại null
hay không.
Sử dụng null
các phương pháp và thư viện -safe
Có rất nhiều thư viện nguồn mở đảm nhận công việc kiểm tra null
. Một trong những phổ biến nhất là StringUtils
từ Apache Commons. Sử dụng các phương pháp như StringUtils.isBlank()
, isNumeric()
, isWhiteSpace()
v.v. bạn không phải lo lắng về việc ném NullPointerException.
//Методы StringUtils являются null-безопасными, они не вызовут NullPointerException
System.out.println(StringUtils.isEmpty(null));
System.out.println(StringUtils.isBlank(null));
System.out.println(StringUtils.isNumeric(null));
System.out.println(StringUtils.isAllUpperCase(null));
Đầu ra: true true false false Chưa hết, trước khi sử dụng, đừng quên đọc tài liệu null
về các phương thức và lớp an toàn. Đây là một trong những thủ thuật Java hay nhất giúp mang lại những cải tiến to lớn mà không cần nhiều nỗ lực.
Cố gắng không trả về null
từ một phương thức, tốt hơn là trả về một bộ sưu tập trống
Đây là một mẹo lập trình Java hay khác mà Joshua Bloch mô tả trong cuốn sách Java: Lập trình hiệu quả của mình. Khi trả về các bộ sưu tập hoặc mảng trống, hãy đảm bảo rằng việc gọi các phương thức cơ bản như size()
hoặc length()
không tạo ra Ngoại lệ NullPointerException. Lớp này Collections
khai báo cụ thể việc triển khai thuận tiện các danh sách, bộ và từ điển trống: Collections.EMPTY_LIST
, Collections.EMPTY_SET
và Collections.EMPTY_MAP
. Ví dụ:
public List getOrders(Customer customer){
List result = Collections.EMPTY_LIST;
return result;
}
Tương tự, bạn có thể sử dụng Collections.EMPTY_SET
nó Collections.EMPTY_MAP
thay vì trả về null
.
Sử dụng chú thích @NotNull và @Nullable
Trong phần mô tả các phương thức của mình, bạn có thể xác địnhnull
các quy ước an toàn cho phương thức bằng cách sử dụng các chú thích @NotNull
và @Nullable để cho biết liệu một phương thức có thể trả về null
hay không. Các trình biên dịch và IDE hiện đại có thể sử dụng các chú thích này để phân tích mã của bạn và đưa ra lời khuyên thích hợp, ví dụ: về việc thiếu kiểm tra null
hoặc ngược lại, về khả năng loại bỏ kiểm tra không cần thiết đang làm tắc nghẽn mã. Ví dụ: các chú thích như vậy được IntelliJ IDE và FindBugs hỗ trợ và chúng cũng được bao gồm trong JSR 305. Nhưng ngay cả khi IDE của bạn không hỗ trợ các chú thích như vậy thì bản thân chúng vẫn là tài liệu tốt. Nhìn vào @NotNull
và @Nullable
lập trình viên sẽ dễ dàng hiểu được nơi nào cần thêm dấu kiểm null
và nơi nào không. Nhân tiện, đây là một cách thực hành khá mới đối với các lập trình viên Java và sẽ mất thời gian để nó lan rộng.
Tránh việc tự động đóng hộp và tự động mở hộp không cần thiết trong mã của bạn
Điều này không chỉ dẫn đến việc tạo ra các đối tượng tạm thời không cần thiết mà việc tự động đóng hộp còn có thể ném ra ngoại lệ NullPointerException nếu lớp trình bao bọc lànull
. Ví dụ: đoạn mã sau sẽ ném ra ngoại lệ NullPointerException nếu mục nhập người không chứa số điện thoại và trả về null
.
Person ram = new Person("ram");
int phone = ram.getPhone();
Khi sử dụng tính năng tự động đóng hộp hoặc tự động hủy hộp thư, không chỉ các đẳng thức mà cả các bất đẳng thức <
> đều >
có thể dẫn đến Ngoại lệ NullPointerException.
Tuân theo các quy ước và xác định các giá trị mặc định hợp lý.
Một trong những cách tốt nhất để tránh NullPointerException trong Java là khai báo và tuân thủ đúng các quy ước mã hóa. Hầu hết các ngoại lệ NullPointer xảy ra khi bạn cố gắng tạo một đối tượng mà không có tất cả dữ liệu và phần phụ thuộc mà nó yêu cầu. Bằng cách ngăn chặn việc tạo các đối tượng chưa hoàn thành bằng cách khéo léo từ chối các yêu cầu đó, bạn sẽ tự cứu mình khỏi một số lượng lớn NullPointerExceptions trong tương lai. Tương tự, nếu bạn cho phép tạo đối tượng, bạn nên chọn giá trị mặc định hợp lý. Ví dụ: một đối tượng lớpEmployee
không thể được tạo nếu không có tên và id
, nhưng có thể không có số điện thoại. Trong trường hợp này, các đối tượng Employee
không có số có thể trả về số 0 null
. Mặc dù hành vi như vậy của đối tượng nên được suy nghĩ trước - có thể dễ kiểm tra null
hơn là gọi đến một số không tồn tại. Trong trường hợp này, việc có thêm các điều kiện về trường nào có null
và trường nào không sẽ giúp đưa ra quyết định đúng đắn. Nói chung, sự lựa chọn giữa việc dừng chương trình ngay lập tức hay chỉ định null
nó là một quyết định thiết kế quan trọng và một khi bạn đã đưa ra lựa chọn, bạn phải tuân theo nó một cách nhất quán.
Đặt các hạn chế ở cấp DBMS
Khi sử dụng cơ sở dữ liệu để lưu trữ các đối tượng chương trình của bạn, chẳng hạn như Khách hàng hoặc Đơn đặt hàng, bạn nên chỉ định "null
tính chất" của các đối tượng ở cấp DBMS, sử dụng các hạn chế bảng thích hợp. Cơ sở dữ liệu thường chứa thông tin từ nhiều nguồn và việc đưa ra các biện pháp kiểm tra các giá trị còn thiếu sẽ cải thiện tính toàn vẹn của dữ liệu của bạn. Ngoài ra, sự hiện diện của các bước kiểm tra null ở cấp DBMS sẽ giảm chúng trong mã Java của bạn: bằng cách tải dữ liệu từ cơ sở dữ liệu vào các đối tượng Java, bạn có thể chắc chắn về sự hiện diện của chúng và xóa " != null
" không cần thiết khỏi mã chương trình.
Sử dụng mẫu đối tượng Null
TạoNull
các -objects đặc biệt là một cách khác để tránh NullPointerExcpetion trong Java. Giả sử rằng một số phương thức trong ứng dụng của chúng ta trả về một đối tượng mà chương trình sau đó sẽ làm việc bằng cách gọi các phương thức của nó. Ví dụ: phương thức Collection.iterator()
trả về một đối tượng của lớp Iterator
được sử dụng để lặp qua bộ sưu tập. Sau đó, nếu đối tượng ban đầu không có bất kỳ trình lặp nào, null
thay vào đó bạn có thể trả về một Null
-object đặc biệt có phương thức hasNext()
luôn trả về false
. Vậy thôi, bạn đọc thân mến, đây là nơi tôi kết thúc các mẹo của mình để loại bỏ các lỗi NullPointerException trong chương trình Java. Bạn sẽ đánh giá cao sự hữu ích của những quy tắc đơn giản và không nặng nề này. Xin nhắc lại, nếu bạn muốn chia sẻ bất kỳ thủ thuật NullPointerException nào khác trong các chương trình Java, vui lòng thực hiện điều đó trong phần nhận xét. Được dịch riêng cho sinh viên JavaRush. Nguyên bản
GO TO FULL VERSION