java如何判断一个对象是否为空对象
作者:码猿笔记 发布时间:2023-12-11 06:53:59
最近项目中遇到一个问题,在用户没填数据的时候,我们需要接收从前端传过来的对象为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()就可以返回属性描述器。
由于没有太多研究就不多介绍了。
来源:https://blog.csdn.net/qq_39654841/article/details/105206621


猜你喜欢
- 本人小菜一个。目前只见过两种弹出框的实现方式,第一种是最常见的PopupWindow,第二种也就是Activity的方式是前几天才见识过。感
- 客户端获取后台支付API请求参数的设计参数样例:{data: {method: 1,platform: 1,version:"1.
- public interface ArraySQL 类型 ARRAY 在 java 编程语言中的映射关系。默认情况下,Array 值是对 S
- Android SDK已经提供有进度条组件ProgressDialog组件,但用的时候我们会发现可能风格与我们应用的整体风格不太搭配,而且P
- 1. 准备工作需要提前安装好Elasticsearch,访问地址:http://127.0.0.1:9200/ 得到以下结果,得到clust
- 在程序开发过程中,LOG是广泛使用的用来记录程序执行过程的机制,它
- SpringBootTest单元测试报错@RunWith(SpringRunner.class)@SpringBootTest(classe
- 前言什么是AptAPT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(But
- 说明本实例能够监控聚划算的抢购按钮,在聚划算整点聚的时间到达时自动弹开页面(URL自己定义)。可以自定义监控持续分钟数,同时还可以通过多线程
- 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义。通过
- 在分布式系统架构中,如果一个应用不能对来自依赖的故障进行隔离,那该应用本身就处在被拖垮的风险中。 因此,为了构建稳定、可靠的分布式系统,我们
- 本篇文章主要介绍了详解Xamarin.Android 利用Fragment实现底部菜单,分享给大家,具体如下:效果图:第一步:添加引用引用
- 本文实例讲述了Java中缀表达式转后缀表达式实现方法。分享给大家供大家参考,具体如下:本文先给出思路与方法,最后将给出完整代码项目实战:ht
- 本文实例为大家分享了安卓实现单行多列横向滚动,供大家参考,具体内容如下<GridLayout android:layou
- 前言记得在介绍 motion_toast 一篇的时候,开篇有一张动图,边框是渐变色而且感觉是流动的。这个动效挺有趣的,当时也有人问怎么实现,
- Android 设置颜色的方法总结Android中有几种设置界面背景及文字颜色的方法,下面由浅入深分别介绍Android中设置颜色的几种方法
- 前段时间spring boot 2.0发布了,与之对应的spring cloud Finchley版本也随之而来了,两者之间的关系和版本对应
- AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合。其实AsyncTask并不是那么好,甚至有些糟糕。本文
- 在前面的文章中,我们分析了淘宝android客户端的一些界面实现和用户体验,今天这篇文章,主要介绍如何使用自定义控件,实现抢购倒计时的功能。
- 一、什么是热部署?热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。二、什么是SpringBoot热部署?SpringBoot