java 判断一个对象是否为空对象

java 判断一个对象是否为空对象最近项目中遇到一个问题,在用户没填数据的时候,我们需要接收从前端传过来的对象为null,但是前端说他们一个一个判断特别麻烦,只能传个空对象过来,我第一个想法就是可以通过反射来判断对象是否为空。第一版:User.javapublicclassUser{privateStringusername;privateBooleanactive;priva…

大家好,又见面了,我是你们的朋友全栈君。

最近项目中遇到一个问题,在用户没填数据的时候,我们需要接收从前端传过来的对象为null,但是前端说他们一个一个判断特别麻烦,只能传个空对象过来,我第一个想法就是可以通过反射来判断对象是否为空。

第一版:

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 方法数量
                int nullValueCount = 0; // 结果为空

                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));
    }
}

结果:

true

第一版 获取一个类的声明的方法,判断方法如果以get或者is开头就是get方法,然后通过反射调用改方法获取结果,再判断结果是否为空,如果结果为null的话就把nullValueCount+1,最后返回结果为空的值的数量和get方法数量比较的结果,如果两者数量相同则说明该对象为空,反之不为空。
第一版也可以判断一个对象是否为空,但前提是对象必须使用包装类,没有默认值的就不行了,当然你也可以根据类型和返回值结果来判断对象是否为空,但是如果想忽略某个属性不做判断,改起来就有点麻烦了。 后来想知道spring 的BeanUtils 是怎么实现属性复制的就看了一下,发现了新的方法,于是就有了第二版。

第二版:

/** * 判断对象是否为空, * @param obj * @param ignoreProperties 忽略的属性 * @return 如果get 方法的数量等于 属性为空的数量 返回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; // 结果为空的属性数量 初始化为1 去除Object的getClass方法
            int propertyCount = propertyDescriptors.length; // 属性数量
            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;
    }

第一版和第二版思想基本都是一样的,都是通过读方法去判断返回值是否为空,只不过第二版在第一版上加强了可以忽略属性这个功能。
通过spring 的beanutils发现PropertyDescriptor这个类,从名字看来是个属性描述器,描述属性相关的东西,通过属性描述器可以获取bean的属性名称,读写方法,使用起来还挺方便。
通过Introspector内省类的静态方法getBeanInfo(Class<?> beanClass)获取BeanInfo,然后通过BeanInfo对象的getPropertyDescriptors()就可以返回属性描述器。
由于没有太多研究就不多介绍了。
如果你还有其他方法判断一个对象是否为空请留言,谢谢

能力有限,水平一般,如有错误,请多指出。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/135219.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 时序数据库 VS 工业实时数据库「建议收藏」

    时序数据库 VS 工业实时数据库「建议收藏」时序数据库和实时数据库到底有啥区别?本期我们就来聊聊时序数据库和传统工业实时数据库的那些事儿。

  • oracle删除表时索引是否删除_oracle索引类型

    oracle删除表时索引是否删除_oracle索引类型DML性能低下,其中最严重的原因之一是无用索引的存在。所有SQL的插入,更新和删除操作在它们需要在每一行数据被改变时修改大量索引的时候会变得更慢。许多Oracle管理人员只要看见在一个SQL查询的WHERE语句出现了一列的话就会为它分配索引。虽然这个方法能够让SQL运行得更快速,但是基于功能的Oracle索引使得数据库管理人员有可能在数据表的行上过度分配索引。过度分配索引会严重影响关键Oracl…

  • notifyAll()_notify for

    notifyAll()_notify for下面这段代码suclassCalculaterextendsThread{ publicinttotal=1; publicvoidrun(){ System.out.println(“Calculatorrun”); synchronized(this){ for(inti=1;i<10;i++){ total*=i; }

  • Eclipse中建多层级包时出现的问题「建议收藏」

    Eclipse中建多层级包时出现的问题「建议收藏」最近一直在学习idea的使用,好久没有用Eclipse了,今天想试着写一个功能,但是在Eclipse中创建包时出现问题了。创建的包都成为平级了。那么Eclipse中如何创建多层包呢?解决方案:    方法一:         1)先在src文件夹下创建com包,在com包里面创建一个类,例如:点击Finish就会出现如下:    2)以此类推建想要建的包,在删除之前的Test类即可。以下是我的效果…

  • 单源最短路径dijkstra算法_dijkstra是谁

    单源最短路径dijkstra算法_dijkstra是谁年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用 10000 个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:”嗯,如果你能够替我弄到大祭司的皮袄,我可以只要 8000 金币。如果你能够弄来他的水晶球,那么只要 5000 金币就行了。”探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或

  • 基于MATLAB GUI的串口通信

    基于MATLAB GUI的串口通信之前学过单片机对于串口通信比较了解最近在学习MATLAB发现它还可以控制串口于是通过MATLAB的GUI创建了一个串口通信的小软件效果如下如果没有单片机或者其他硬件的话我们可以直接用软件模拟串口本人选择了ConfigureVirtualSerialPortDriver这个软件软件网上就有下一个使用几天就行了 选…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号