java如何判斷一個(gè)對(duì)象是否為空對(duì)象
最近項(xiàng)目中遇到一個(gè)問(wèn)題,在用戶沒(méi)填數(shù)據(jù)的時(shí)候,我們需要接收從前端傳過(guò)來(lái)的對(duì)象為null,但是前端說(shuō)他們一個(gè)一個(gè)判斷特別麻煩,只能傳個(gè)空對(duì)象過(guò)來(lái),我第一個(gè)想法就是可以通過(guò)反射來(lái)判斷對(duì)象是否為空。
第一版:
User.java
public class User {
? ? private String username;
? ? private Boolean active;
? ? private Long id;
? ? // 省略get和set方法
}ReflectUtil.java
public class ReflectUtil {
? ? public static boolean isObjectNull(Object obj){
? ? ? ? if (obj != null) {
? ? ? ? ? ? Class<?> objClass = obj.getClass();
? ? ? ? ? ? Method[] declaredMethods = objClass.getDeclaredMethods();
? ? ? ? ? ? if (declaredMethods.length > 0) {
? ? ? ? ? ? ? ? int methodCount = 0; // get 方法數(shù)量
? ? ? ? ? ? ? ? int nullValueCount = 0; // 結(jié)果為空
? ? ? ? ? ? ? ? for (Method declaredMethod : declaredMethods) {
? ? ? ? ? ? ? ? ? ? String name = declaredMethod.getName();
? ? ? ? ? ? ? ? ? ? if (name.startsWith("get") || name.startsWith("is")){
? ? ? ? ? ? ? ? ? ? ? ? methodCount += 1;
? ? ? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? ? ? Object invoke = declaredMethod.invoke(obj);
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (invoke == null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? nullValueCount += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? } catch (IllegalAccessException | InvocationTargetException e){
? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? return methodCount == nullValueCount;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return false;
? ? }
}TestReflect.java
public class TestReflect {
? ? public static void main(String[] args) {
? ? ? ? User user = new User();
? ? ? ? System.out.println(ReflectUtil.isObjectNull(user));
? ? }
}結(jié)果:
true
第一版 獲取一個(gè)類的聲明的方法,判斷方法如果以get或者is開頭就是get方法,然后通過(guò)反射調(diào)用改方法獲取結(jié)果,再判斷結(jié)果是否為空,如果結(jié)果為null的話就把nullValueCount+1,最后返回結(jié)果為空的值的數(shù)量和get方法數(shù)量比較的結(jié)果,如果兩者數(shù)量相同則說(shuō)明該對(duì)象為空,反之不為空。
第一版也可以判斷一個(gè)對(duì)象是否為空,但前提是對(duì)象必須使用包裝類,沒(méi)有默認(rèn)值的就不行了,當(dāng)然你也可以根據(jù)類型和返回值結(jié)果來(lái)判斷對(duì)象是否為空,但是如果想忽略某個(gè)屬性不做判斷,改起來(lái)就有點(diǎn)麻煩了。 后來(lái)想知道spring 的BeanUtils 是怎么實(shí)現(xiàn)屬性復(fù)制的就看了一下,發(fā)現(xiàn)了新的方法,于是就有了第二版。
第二版:
/**
? ? ?* ?判斷對(duì)象是否為空,
? ? ?* @param obj
? ? ?* @param ignoreProperties 忽略的屬性
? ? ?* @return 如果get 方法的數(shù)量等于 屬性為空的數(shù)量 返回true,否則false
? ? ?*/
? ? public static boolean isNullObject(Object obj , String... ignoreProperties) throws IntrospectionException {
? ? ? ? if (obj != null) {
? ? ? ? ? ? Class<?> objClass = obj.getClass();
? ? ? ? ? ? BeanInfo beanInfo = Introspector.getBeanInfo(objClass);
? ? ? ? ? ? PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
? ? ? ? ? ? List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
? ? ? ? ? ? int count = 1; // 結(jié)果為空的屬性數(shù)量 初始化為1 去除Object的getClass方法
? ? ? ? ? ? int propertyCount = propertyDescriptors.length; // 屬性數(shù)量
? ? ? ? ? ? if (ignoreList != null){
? ? ? ? ? ? ? ? propertyCount -= ignoreList.size();
? ? ? ? ? ? }
? ? ? ? ? ? for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
? ? ? ? ? ? ? ? Method readMethod = propertyDescriptor.getReadMethod();
? ? ? ? ? ? ? ? String name = propertyDescriptor.getName();
? ? ? ? ? ? ? ? if (readMethod != null && (ignoreList == null || !ignoreList.contains(name))) {
? ? ? ? ? ? ? ? ? ? Class<?> returnType = readMethod.getReturnType();
? ? ? ? ? ? ? ? ? ? String typeName = returnType.getSimpleName();
? ? ? ? ? ? ? ? ? ? Object invoke = null;
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? invoke = readMethod.invoke(obj);
? ? ? ? ? ? ? ? ? ? ? ? if (invoke == null) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? count+=1;
? ? ? ? ? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? ? ? ? ? switch (typeName) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "String":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ("".equals(invoke.toString().trim())) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "Integer":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((Integer) invoke <= 0) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "int":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((int) invoke <= 0) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "double":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((double) invoke <= 0.0d) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "Double":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((Double) invoke <= 0.0D) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "float":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((float) invoke <= 0.0f) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "Float":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((Float) invoke <= 0.0F) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "Long":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((Long) invoke <= 0L) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? case "long":
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((long) invoke <= 0L) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count += 1;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? } catch (IllegalAccessException | InvocationTargetException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return propertyCount == count;
? ? ? ? }
? ? ? ? return true;
? ? }第一版和第二版思想基本都是一樣的,都是通過(guò)讀方法去判斷返回值是否為空,只不過(guò)第二版在第一版上加強(qiáng)了可以忽略屬性這個(gè)功能。
通過(guò)spring 的beanutils發(fā)現(xiàn)PropertyDescriptor這個(gè)類,從名字看來(lái)是個(gè)屬性描述器,描述屬性相關(guān)的東西,通過(guò)屬性描述器可以獲取bean的屬性名稱,讀寫方法,使用起來(lái)還挺方便。
通過(guò)Introspector內(nèi)省類的靜態(tài)方法getBeanInfo(Class<?> beanClass)獲取BeanInfo,然后通過(guò)BeanInfo對(duì)象的getPropertyDescriptors()就可以返回屬性描述器。
由于沒(méi)有太多研究就不多介紹了。
到此這篇關(guān)于java如何判斷一個(gè)對(duì)象是否為空對(duì)象的文章就介紹到這了,更多相關(guān)java 判斷對(duì)象是否為空內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot使用Log4j的知識(shí)點(diǎn)整理
在本篇文章里小編給大家整理的是關(guān)于SpringBoot使用Log4j的知識(shí)點(diǎn),需要的朋友們可以參考學(xué)習(xí)下。2020-02-02
eclipse maven maven-archetype-webapp 創(chuàng)建失敗問(wèn)題解決
這篇文章主要介紹了eclipse maven maven-archetype-webapp 創(chuàng)建失敗問(wèn)題解決的相關(guān)資料,需要的朋友可以參考下2016-12-12
SpringBoot做junit測(cè)試的時(shí)候獲取不到bean的解決
這篇文章主要介紹了SpringBoot做junit測(cè)試的時(shí)候獲取不到bean的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
淺談緩沖字符流 BufferedReader BufferedWriter用法
這篇文章主要介紹了緩沖字符流 BufferedReader BufferedWriter的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
運(yùn)行Jar包出現(xiàn)提示xxx中沒(méi)有主清單屬性報(bào)錯(cuò)問(wèn)題解決方法
這篇文章主要介紹了運(yùn)行Jar包出現(xiàn):xxx中沒(méi)有主清單屬性報(bào)錯(cuò),當(dāng)出現(xiàn)報(bào)錯(cuò):xxx中沒(méi)有主清單屬性,解決方法也很簡(jiǎn)單,在pom.xml配置中,加上相應(yīng)配置即可,需要的朋友可以參考下2023-08-08
SpringCloud Zuul在何種情況下使用Hystrix及問(wèn)題小結(jié)
這篇文章主要介紹了SpringCloud Zuul在何種情況下使用Hystrix 及問(wèn)題小結(jié),感興趣的朋友跟隨小編一起看看吧2018-11-11
Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例
這篇文章主要介紹了Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例,在一些業(yè)務(wù)需求中我們經(jīng)常需要使用郵箱進(jìn)行驗(yàn)證碼的收取,本文通過(guò)簡(jiǎn)單的代碼實(shí)例來(lái)說(shuō)明,需要的朋友可以參考下2024-01-01

