如何優雅的判斷一個對象的屬性是否全部爲空

有一些業務場景下,我們需要判斷某個對象的屬性是否全部爲空。該怎麼做呢?

馬上能想到的一個方案是,一個一個判斷對象中的屬性。這個倒也可以,但是如果要判斷的對象比較多,就得給每個對象寫一個判斷方法(因爲每個對象的屬性都不一樣)。

其實我們可以利用 java 的反射機制,比較優雅的實現。代碼其實也很簡單,

public class ObjectIsNullUitl {
    public static boolean checkFieldAllNull(Object object) throws IllegalAccessException {
        for (Field f : object.getClass().getDeclaredFields()) {
            System.out.println("name:" + f.getName());
            f.setAccessible(true);
            if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
                continue;
            }
            if (!isEmpty(f.get(object))) {
                return false;
            }
            f.setAccessible(false);
        }
        //父類public屬性
        for (Field f : object.getClass().getFields()) {
            System.out.println("name:" + f.getName());
            f.setAccessible(true);
            if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
                continue;
            }
            if (!isEmpty(f.get(object))) {
                return false;
            }
            f.setAccessible(false);
        }
        return true;
    }

    private static boolean isEmpty(Object object) {
        if (object == null) {
            return true;
        }
        if (object instanceof String && (object.toString().equals(""))) {
            return true;
        }
        if (object instanceof Collection && ((Collection) object).isEmpty()) {
            return true;
        }
        if (object instanceof Map && ((Map) object).isEmpty()) {
            return true;
        }
        if (object instanceof Object[] && ((Object[]) object).length == 0) {
            return true;
        }
        return false;
    }
}

簡單說下原理,

isEmpty 方法除了對象本身的null判斷之外,還會根據對象的實際類型特殊判斷,比如String類型,大部分業務場景下空串("")也是無意義的,和null可以等效處理。

另外,這裏並沒有加Number類型(Integer,Byte等包裝類型的父類),這個主要是考慮到不同的業務場景對於“空值”的定義不一樣,不好統一處理。

if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
                continue;
            }

這一句是讓檢查忽略掉 final static 修飾的屬性,當然這個如果你的業務場景不需要,也可以不加。

然後我們準備一個測試類,

public class Model extends BaseModel{
    private String property1;
    private Integer property2;
    private List<String> property3;
}
public static void main(String[] args) throws InterruptedException, IllegalAccessException {
        Model model = new Model();
        boolean ret = ObjectIsNullUitl.checkFieldAllNull(model);
        System.out.println("ret:" + ret);
    }

輸出的結果是true,因爲我們確實沒有給 model 對象的屬性賦值。

這裏其實有個坑需要特別注意。屬性如果有基本類型(int,byte 等),即使不賦值,判斷的結果也永遠是 false。這是因爲基本類型會有默認值(比如 int 默認值是0),在反射的過程中基本類型會變成包裝類型,那麼 int 就會變成 Integer 對象,並且對象的 intvalue 是0。所以需要判斷是否爲空的對象的屬性儘量不要使用基本類型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章