Search

Java - 避免 NullPointerException 的設計模式

2015-10-21 6:08 PM

Java 的 null 處理算是一位程式設計師由新手進入進階的最好證明

眾所皆知 若 Java 出現 NullPointerException 往往很難找到問題發生所在

但為了方便 又常常使用 null 作為回傳值及初始值

若忘記判斷是否為 null 就很容易出現 NullPointerException

這時光看 Log 檔完全無法得知是哪個變數出錯

為了避免這種狀況發生 我們將搭配使用 Google Guava Library 裡面的 Optional 物件

一來可以告知程式撰寫人員這個參數有可能是 null

二來若是忘記判斷 在取得 null 時將會明顯地告知是哪一行哪一個變數出錯

程式碼範例
// 此處為 Optional 的初始化方式 以取得資料庫資料為範例
public Optional<UserPreference> findByName(String owner, String name) throws SQLException {

    QueryBuilder<UserPreference, Integer> queryBuilder = queryBuilder();

    queryBuilder.limit(1L)
            .where().eq("owner", owner)
            .and().eq("name", name);

    List<UserPreference> list = query( queryBuilder.prepare() );

    // 若沒有資料則以 absent 表示為 null
    if( list.isEmpty() ) return Optional.absent();

    // 若有資料則使用 Optional.of( object ); 建立物件
    return Optional.of( list.get(0) );
}


// 此處以資料庫新增資料作範例
public UserPreference insertWithCheck(String owner, String name, String value) throws SQLException, UnsupportedEncodingException {

    // 首先取得資料
    Optional<UserPreference> userPreferenceOptional = getUserPreference(owner, name);

    // 檢查資料是否為 null 若否則更新資料
    if( userPreferenceOptional.isPresent() ){
        return userPreferenceDao.updateValue( userPreferenceOptional.get(), name, value, encrypted);
    }

    // 資料為 null 則直接新增
    return userPreferenceDao.insert(owner, name, value, encrypted);
}

// 到資料庫撈出單筆資料
public Optional<UserPreference> getUserPreference(String owner, String name) throws SQLException {
    return findByName(owner, name);
}

// 此方法可以在 null 時報錯
userPreferenceOptional.get();

// 此方法可以在 null 時賦予預設值
userPreferenceOptional.or( defaultValue );

// 此方法可以在 null 時直接回傳 null
userPreferenceOptional.orNull();
各項資料連結
GitHub - Google Guava
MavenRepository - Google Guava

No comments:

Post a Comment