GP Coder

Trang chia sẻ kiến thức lập trình Java

  • Java Core
    • Basic Java
    • OOP
    • Exception Handling
    • Multi-Thread
    • Java I/O
    • Networking
    • Reflection
    • Collection
    • Java 8
  • Design pattern
    • Creational Pattern
    • Structuaral Pattern
    • Behavior Pattern
  • Web Service
    • SOAP
    • REST
  • JPA
  • Java library
    • Report
    • Json
    • Unit Test
  • Message Queue
    • ActiveMQ
    • RabbitMQ
  • All
Trang chủ Java Core Exception Handling Tránh lỗi NullPointerException trong Java như thế nào?

Tránh lỗi NullPointerException trong Java như thế nào?

Đăng vào 06/08/2018 . Được đăng bởi GP Coder . 10468 Lượt xem . Toàn màn hình

Trong bài này, tôi muốn chia sẽ với các bạn một vài kinh nghiệm code để hạn chế lỗi NullPointerException (NPE) trong chương trình Java.

Nguyên tắc chung: KHÔNG khởi tạo, truyền tham số, trả kết quả về là một giá trị NULL và giữ cho code càng đơn giản càng tốt.

Dưới đây là một vài kỹ thuật hạn chế lỗi NPE:

Nội dung

  • 1 Return giá trị
  • 2 Luôn kiểm tra NULL trước khi sử dụng
  • 3 Kiểm tra Null-safe
  • 4 Hạn chế sử dụng multi-dot syntax
  • 5 Khởi tạo giá trị trước khi sử dụng
  • 6 Sử dụng tính năng mới trong Java 8 – Optional

Return giá trị

Return một EMPTY collection thay vì giá trị NULL

Trong Java, mặc định một biến Object được định nghĩa sẽ có giá trị null. Các Collection như List, Set, Map, … được sử dụng rất nhiều trong ứng dụng. Nếu mọi phương thức đều return về null, thì khi sử dụng chúng ta phải kiểm tra null ở khắp mọi người và điều này không cần thiết cũng như gây code rất khó đọc.

Một ví dụ dễ thấy nhất là các bạn có một class DAO, class này có nhiệm vụ truy vấn dữ liệu từ database.


class UserDao {
	public List<User> getUsers () {
		// Query database and convert to list
		boolean hasData = false;
		if (hasData) {
			// return list of users
		}
		// There is no user
		return null;
	}
}

class UserService {
	private UserDao dao = new UserDao();
	public void showUsers () {
		List<User> users = dao.getUsers();
		if (users != null) { // Must be checked null
			// Show user information
		}
	}
	
	public void exportToCsv () {
		List<User> users = dao.getUsers();
		if (users != null) { // Must be checked null
			// Export to csv file
		}
	}
}

Như bạn thấy, chúng ta phải check null ở khắp nơi (showUsers, exportToCsv). Thử tưởng tượng nếu chúng ta return về một empty list thì khi đó chúng ta chỉ việc lấy ra và sử dụng, không cần quan tâm những đoạn code vô nghĩa về mặt business.

Đối với Collection, chúng ta có thể sử dụng từ khóa new hoặc sử dụng các phương thức sau để khởi tạo mọi Collection rỗng sử dụng lớp tiện ích java.util.Collections.

  • List: Collections.emptyList()
  • Set: Collections.emptySet()
  • Map: Collections.emptyMap()

Return một EMPTY String

Các bạn có thể return một chuỗi rỗng “” hoặc sử dụng một constant có sẵn, chẳng hạn org.apache.commons.lang.StringUtils.EMPTY

Return một giá trị Unknown/ Default thay vì Null

Sử dụng Null Object Pattern:


public User getUser(UserType type){
    switch(type) {
        case ADMIN:
            return getAdmin();
        case MANAGER:
            return getManager();
        default:
            break;
    }
    return null;
}

Có thể viết tránh lỗi NULL như sau:


public User getUser(UserType type){
    switch(type) {
        case ADMIN:
            return getAdmin();
        case MANAGER:
            return getManager();
        default:
        break;
    }
    return NullUser ();
}

class NullUser extends User {
    // Implement all abstract methods of User
    // Override neccessary methods to drive to do "Nothing" or "Default" action.
}

Luôn kiểm tra NULL trước khi sử dụng

Điều này nói ra thì hơi trái ngược với return về empty data và không cần check null. Nếu tất cả mọi người đều tuân thủ theo quy ước chung về return empty data thay vì null thì chúng ta sẽ không cần check null, mọi thức qua tuyệt vời. Nhưng đôi khi có một số trường hợp chúng ta cần return về null hay trong các hệ thống code cũ (legacy code) thì điều này là nên làm.

Kiểm tra Null-safe

Ví dụ:


if("Hello".equals(hello)) { }

Thay vì:


if(hello != null) {
    if(hello.equals("Hello")) { }
}

// hoặc

if(hello.equals("Hello")) { }

Hạn chế sử dụng multi-dot syntax

Tuân thủ theo Law of Demeter Principle (LoD.


getLoggedinUser().getUser().getRole().setRoleName("Developer");

Như bạn thấy đoạn code trên rất dễ gặp lỗi NPE nếu bất kỳ object LoggedinUser, User, hay Role trả về giá trị null.

Khởi tạo giá trị trước khi sử dụng

Một trong những thói quen tốt giúp giảm NPE rất nhiều là khởi tạo giá trị empty cho các property khi một instance của object được tạo.

Có một số chỗ có thể khởi tạo giá trị cho property như sau:

Khởi tạo ngay khi khai báo property :


private List<User> users = new ArrayList<>();

Khởi tạo trong hàm constructor:


public UserManager() {
    users = new ArrayList<>();
}

Khởi tạo trong Getter:


public List<User> getUsers() {
    if(users == null) {
        users = new ArrayList<>();
    }
    return users ;
}

Sử dụng tính năng mới trong Java 8 – Optional

Trong Java 8, chúng ta có một lớp Optional<T> mới được giới thiệu trong gói java.util. Nó được sử dụng để kiểm tra xem một biến có giá trị tồn tại giá trị hay không. Ưu điểm chính của cấu trúc mới này là không có quá nhiều kiểm tra null và tránh lỗi NullPointerException (NPE) lúc runtime.

Chi tiết về Optional, các bạn hãy tham khảo ở bài viết : Optional trong Java 8.

 

4.7
18
Nếu bạn thấy hay thì hãy chia sẻ bài viết cho mọi người nhé! Và Donate tác giả

Shares

Chuyên mục: Basic Java, Exception Handling, Java Core Được gắn thẻ: Exception

Giới thiệu WatchService API trong Java
Các nguyên lý thiết kế hướng đối tượng – SOLID

Có thể bạn muốn xem:

  • Kiểu dữ liệu Ngày Giờ (Date Time) trong java (29/10/2017)
  • Xử lý ngoại lệ đối với trường hợp ghi đè phương thức trong java (07/11/2017)
  • Enum trong java (09/11/2017)
  • Sao chép các phần tử của một mảng sang mảng khác như thế nào? (27/11/2017)
  • Sử dụng JDBC API thực thi câu lệnh truy vấn dữ liệu (07/10/2019)

Bình luận

bình luận

Tìm kiếm

Bài viết mới

  • Clean code 13/01/2024
  • Giới thiệu CloudAMQP – Một RabbitMQ server trên Cloud 02/10/2020
  • Kết nối RabbitMQ sử dụng Web STOMP Plugin 19/06/2020
  • Sử dụng publisher confirm trong RabbitMQ 16/06/2020
  • Sử dụng Dead Letter Exchange trong RabbitMQ 13/06/2020

Xem nhiều

  • Hướng dẫn Java Design Pattern – Factory Method (99394 lượt xem)
  • Hướng dẫn Java Design Pattern – Singleton (99025 lượt xem)
  • Giới thiệu Design Patterns (89790 lượt xem)
  • Lập trình đa luồng trong Java (Java Multi-threading) (87930 lượt xem)
  • Giới thiệu về Stream API trong Java 8 (85271 lượt xem)

Nội dung bài viết

  • 1 Return giá trị
  • 2 Luôn kiểm tra NULL trước khi sử dụng
  • 3 Kiểm tra Null-safe
  • 4 Hạn chế sử dụng multi-dot syntax
  • 5 Khởi tạo giá trị trước khi sử dụng
  • 6 Sử dụng tính năng mới trong Java 8 – Optional

Lưu trữ

Thẻ đánh dấu

Annotation Authentication Basic Java Behavior Pattern Collection Creational Design Pattern Cấu trúc điều khiển Database Dependency Injection Design pattern Eclipse Exception Executor Service Google Guice Gson Hibernate How to Interceptor IO Jackson Java 8 Java Core JDBC JDK Jersey JMS JPA json JUnit JWT Message Queue Mockito Multithreading OOP PowerMockito RabbitMQ Reflection Report REST SOAP Structuaral Pattern Swagger Thread Pool Unit Test Webservice

Liên kết

  • Clean Code
  • JavaTpoint
  • Refactoring Guru
  • Source Making
  • TutorialsPoint
  • W3Schools Online Web Tutorials

Giới thiệu

GP Coder là trang web cá nhân, được thành lập với mục đích lưu trữ, chia sẽ kiến thức đã học và làm việc của tôi. Các bài viết trên trang này chủ yếu về ngôn ngữ Java và các công nghệ có liên quan đến Java như: Spring, JSF, Web Services, Unit Test, Hibernate, SQL, ...
Hi vọng góp được chút ít công sức cho sự phát triển cộng đồng Coder Việt.

Donate tác giả

Tìm kiếm các bài viết của GP Coder với Google Search

Liên hệ

Các bạn có thể liên hệ với tôi thông qua:
  • Trang liên hệ
  • Linkedin: gpcoder
  • Email: contact@gpcoder.com
  • Skype: ptgiang56it

Follow me

Copyright 2025 © GP Coder · All Rights Reserved · Giới thiệu · Chính sách · Điều khoản · Liên hệ ·

Share

Blogger
Delicious
Digg
Email
Facebook
Facebook messenger
Flipboard
Google
Hacker News
Line
LinkedIn
Mastodon
Mix
Odnoklassniki
PDF
Pinterest
Pocket
Print
Reddit
Renren
Short link
SMS
Skype
Telegram
Tumblr
Twitter
VKontakte
wechat
Weibo
WhatsApp
X
Xing
Yahoo! Mail

Copy short link

Copy link