Java反射应⽤:判断对象是否为NULL
⼀、背景
最近在做对接美国的EasyPost快递平台时,发现使⽤Objects.isNull()判断EasyPost返回的序列化之后的空实体(JSON体为:{})时,返回结果并不是false;然后情不⾃禁就⾃⼰写了个使⽤反射判断Java对象是否为“NULL”的⼯具类。
不过最后处于效率的考虑,我并没⽤,⽽是使⽤业务上的唯⼀约束做进⼀步的判空处理。这个⼯具类就送给有缘⼈吧,哈哈哈!
最终版⼯具类
只想知道最终⼯具类的⽼哥,请copy如下代码:
package com.flect;
import flect.Field;
import flect.Type;
import java.util.HashSet;
import java.util.Objects;
/**
* @author Saint
*/
public class CheckObjectIsNullUtils {
/
**
* 不纳⼊判空逻辑的field属性
*/
static final HashSet<String> fieldHash =new HashSet<>(4);
static{
fieldHash.add("serialVersionUID");
}
/**
* 判断⼀个对象是否为null
*
* @param object
* @return
*/
public static boolean isNull(Object object){
// 获取object的Class对象
Class<?> clazz = Class();
// 获取对象的所有属性
Field[] fields = DeclaredFields();
// 定义返回结果
boolean flag =true;
for(Field field : fields){
// 使⾮Public类型的属性可以被访问
field.setAccessible(true);
Object fieldValue = null;
Type type = null;
try{
fieldValue = (object);
// 获取到属性类型
type = Type();
// 获取属性名称
String fieldName = Name();
ains(fieldName)){
continue;
}
// TODO 实际应⽤中建议删掉这⼀⾏,仅做测试使⽤
System.out.println("属性类型:"+ type +", 属性名:"+ fieldName +", 属性值:"+ fieldValue);
}catch(Exception e){
// TODO 真实业务场景中,这⾥可以采⽤打⽇志替换
e.printStackTrace();
}
// 只要有⼀个属性值不为null 就返回false 表⽰对象不为null
if(fieldValue != null){
// 如果fieldValue不为null,并且fieldValue的值等于false时,则不认为对象不为空。
if(Objects.TypeName(),"boolean")
&& Objects.equals(fieldValue,false)){
continue;
}else{
flag =false;
break;
}
}
}
return flag;
}
}
⼆、判空⽅式
判断Java对象是否为null可以有两层含义:
(1)第⼀层: 直接使⽤ object == null 去判断,对象为null的时候返回true,不为null的时候返回false。
(2)第⼆层:在object != null 为true的情况 下,进⼀步去判断对象的所有属性是否为null。
1)第⼀层判空
建议使⽤上图的Objects.isNull()⽅法,⽐⾃⼰写null ===xxx更加优雅。当然这⾥所做的是只是对象是否null,如果对象被new出来了,但是它的所有属性都是默认值null,Objects.isNull()⽅法是判断不出来的。
尤其是在前后端交互的过程中,前端传过来的空对象实际是:{},这时对象不为null,但是对象的所有属性为null。
2)使⽤反射做第⼆层判空
User.class
import lombok.AllArgsConstructor; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author Saint
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private Boolean age;
private List<String> hobbies; private boolean student;
}
equals不等于⼯具类:CheckObjectIsNullUtils
import flect.Field;
import flect.Type;
/**
* @author Saint
*/
public class CheckObjectIsNullUtils {
/**
* 判断⼀个对象是否为null
*
* @param object
* @return
*/
public static boolean isNull(Object object){
// 获取object的Class对象
Class<?> clazz = Class();
// 获取对象的所有属性
Field[] fields = DeclaredFields();
// 定义返回结果
boolean flag =true;
for(Field field : fields){
// 使⾮Public类型的属性可以被访问
field.setAccessible(true);
Object fieldValue = null;
try{
fieldValue = (object);
// 获取到属性类型
Type type = Type();
// 获取属性名称
String fieldName = Name();
/
/ TODO 实际应⽤中建议删掉这⼀⾏,仅做测试使⽤
System.out.println("属性类型:"+ type +", 属性名:"+ fieldName +", 属性值:"+ fieldValue);
}catch(Exception e){
// TODO 真实业务场景中,这⾥可以采⽤打⽇志替换
e.printStackTrace();
}
// 只要有⼀个属性值不为null 就返回false 表⽰对象不为null
if(fieldValue != null){
flag =false;
break;
}
}
return flag;
}
}
1>>>>>当含有⼀个boolean类型的属性时
测试类:
/**
* 对象是否为空⼯具-测试类
* @author Saint
*/
public class CheckObjectIsNullTest {
public static void main(String[] args){
User user =new User();
boolean flag = CheckObjectIsNullUtils.isNull(user);
}
}
控制台输出:
属性类型:class java.lang.String, 属性名:name, 属性值:null
属性类型:class java.lang.Boolean, 属性名:age, 属性值:null
属性类型:interface java.util.List, 属性名:hobbies, 属性值:null
属性类型:boolean, 属性名:student, 属性值:false
User对象是否为空: false
从输出上来看,收到boolean类型的影响,结果为false。
另外需要注意的是数据类型: boolean与Boolean
boolean 定义的变量默认值为false,Boolean定义的变量默认值为 null.
ps: 在定义boolean类型变量时,最好不要使⽤ isXxx,因为默认⽣成的get⽅法就是 isXxx(), RPC框架在反向解析的时候,以为对应的属性名是 xxx,从⽽导致属性获取不到,抛出异常。
2>>>>>修改⼯具类,兼容boolean类型的属性
⼯具类:CheckObjectIsNullUtils
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论