網頁

2019/1/28

Java if 判斷物件是否為null寫法

在Java最常寫的就是判斷一個物件是否為null了,寫法有兩種如下

if (obj == null) { ... } // 寫法一,null在後

if (null == object) { ... } // 寫法二,null在前

就效率而言兩者其實沒什麼差別。差別在於第二種寫法,也就是null在前的寫法,可以減少一些除錯的麻煩,例如在下面程式中,呼叫了某個方法取回Map物件,接著要判斷從中取出的Boolean isExist是否為空,此時若不小心把比較符號==誤寫成賦值符號=,則if (isExist = null)的寫法不會提示任何錯誤,只有在運行時才會發生NullPointerException;相反地,若將null改在前面,則編輯器會提示編譯錯誤,因為null無法賦值,所以就不用等到執行時才發現。

public class Main {

    public static void main(String[] args) {
        
        MyService myService = new MyService();
        
        Map<String, Object> map = myService.query();
        Boolean isExist = (Boolean) map.get("isExist");

        if (isExist = null) { // no error
            // ...
        }

        // Yoda condtions
        if (null = isExist) { // compile error
            // ...
        }
        
    }
}

class MyService {
    public Map<String, Object> query() {
        Map<String, Object> map = new HashMap<>();
        map.put("isExist", true);
        // ...
        return map;
    }
}

這種null在前的寫法稱為Yoda conditions,原由是Yoda(就是電影星際大戰中的尤達大師),說話的方式和一般人相反,例如正常的說法「我是菜鳥。」,尤達的說法是「菜鳥我是」。因此Yoda conditions的寫法優點就如上所述,缺點就是可讀性比較差,讀起來就像「若null等於物件,則...」。


不過在Java中只有物件型態為Boolean的情況才有以上的好處,其他形態的物件都會因為賦值結果不為boolean所以在if ()中都會提示編譯錯誤。

那為什麼不乾脆用boolean就好,原因是在某些情況只能使用Boolean,例如上面的Map,或集合如List<Boolean>,或是使用泛型類別(Generic)的情況如下。

public class Main {

    public static void main(String[] args) {

        MyService myService = new MyService();

        User<Boolean> user = myService.getUser();
        Boolean isVip = user.getIsVip();
        if (null = isVip) { // compile error hints
            // ...
        }

    }
}

class MyService {
    public User<Boolean> getUser() {
        User<Boolean> user = new User<>(); // generic only accept wrapper class 'Boolean'
        user.setIsVip(true);
        return user;
    }

}

class User<T> {

    private T isVip;

    public T getIsVip() {
        return isVip;
    }

    public void setIsVip(T isVip) {
        this.isVip = isVip;
    }

}

參考:

沒有留言:

張貼留言