提高开发效率:快速判断Java对象中所有String属性是否为空

引言

在Java开发中,经常需要判断对象中的String属性是否为空。按照往常的写法,就是一个属性一个IF语句的去判断,这种方法在属性较少的情况下还勉强能接受,但是如果碰上很多很多属性都需要判断的时候,就会非常难受。在写了100多行的IF之后,我忍不了了,在确认并没有可以直接用的轮子之后,我决定自己来造这个轮子。程序员果然是最喜欢偷懒的一群人

想法

想要一次性判断完一个对象中所有的String属性,那么就得先知道这个对象中有哪些属性,以及这个属性的类型。
对此,我们可以利用"反射"来获取Java对象中的所有属性。

       // 获取对象的 Class 对象
       Class<?> objectClass = obj.getClass();

       // 获取对象的所有属性
       Field[] fields = objectClass.getDeclaredFields();

       // 遍历属性并输出属性名、类型和值
       for (Field field : fields) {
            // 设置属性可访问,即使是私有属性
            field.setAccessible(true); 

            String fieldName = field.getName();
            Class<?> fieldType = field.getType();

            try {
                Object fieldValue = field.get(obj);
                System.out.println("属性名: " + fieldName);
                System.out.println("属性类型: " + fieldType.getName());
                System.out.println("属性值: " + fieldValue);
                System.out.println();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

判空的语句则可以这样子,使用isEmpty也算是提高了一点点效率。

if (String.class.equals(fieldType) && StringUtils.isEmpty((String) fieldValue)) {
    System.out.println("字段:" + fieldName + " 为空。");
}

优化

这个时候似乎问题都已经解决了,但是我们仍然需要考虑一下效率问题。如果此时有多个对象需要判断,先不管这些对象是否相同,按照这种写法我们是不是每次面对一个对象的时候都要重新反射一遍去获取它的字段和属性?而反射是会影响执行速度的,所以我们应该尽量避免这种浪费资源的写法~

我在这边考虑用缓存的方法去解决这个问题,全部代码如下:

public class ObjectUtil {
    private static Map<Class<?>, Map<String, Field>> fieldCache = new HashMap<>();

    public static void haveEmpty(Object object) {
    	// 打印一下缓存
        for (Map<String, Field> classFieldCache : fieldCache.values()) {
            for (Map.Entry<String, Field> entry : classFieldCache.entrySet()) {
                String key = entry.getKey();
                Field value = entry.getValue();
                System.out.println("Key: " + key);
                System.out.println("Value: " + value);
                System.out.println();
            }
        }
        System.out.println("************小分隔**************");
        // 获取对象的 Class 属性
        Class<?> objectClass = object.getClass();

        Map<String, Field> classFieldCache = fieldCache.get(objectClass);

        // 如果缓存中不存在该类的字段信息,则进行反射获取并缓存起来
        if (classFieldCache == null) {
            classFieldCache = new HashMap<>();
            Field[] fields = objectClass.getDeclaredFields();
            for (Field field : fields) {
                // 设置属性可访问,即使是私有属性
                field.setAccessible(true);
                classFieldCache.put(field.getName(), field);
            }
            fieldCache.put(objectClass, classFieldCache);
        }

        // 遍历属性
        for(Field field : classFieldCache.values()) {
            String fieldName = field.getName();
            Class<?> fieldType = field.getType();

            try{
                Object fieldValue = field.get(object);
                /* 判空操作
                 * 使用 StringUtils 工具类或自定义的静态方法,避免直接调用 isEmpty() 方法,可以提高性能。
                 */
                if (String.class.equals(fieldType) && StringUtils.isEmpty(fieldValue)){
                    System.out.println("字段:" + fieldName+" 为空。");
                }
                System.out.println("属性名: " + fieldName);
                System.out.println("属性类型: " + fieldType.getName());
                System.out.println("属性值: " + fieldValue);
                System.out.println();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

在每次执行前,先判断缓存中是否已有该对象,如果有,则直接开始,如果没有,则先反射。

测试

测试代码

        User user = new User();
        user.setId(1);
        user.setUsername("");
        user.setPassword("123");
        ObjectUtil.haveEmpty(user);
        System.out.println("------------------大分隔-----------------");
        Account account = new Account();
        account.setId(1);
        account.setName("");
        account.setMoney(1.1);
        ObjectUtil.haveEmpty(account);

结果

// 第一次执行,所以缓存内没有东西。
************小分隔**************
属性名: password
属性类型: java.lang.String
属性值: 123

属性名: id
属性类型: int
属性值: 1

字段:username 为空。
属性名: username
属性类型: java.lang.String
属性值: 

------------------大分隔-----------------
// 第二次执行,打印出来上一次缓存的内容
Key: password
Value: private java.lang.String org.example.model.User.password

Key: id
Value: private int org.example.model.User.id

Key: username
Value: private java.lang.String org.example.model.User.username

************小分隔**************
属性名: money
属性类型: java.lang.Double
属性值: 1.1

字段:name 为空。
属性名: name
属性类型: java.lang.String
属性值: 

属性名: id
属性类型: java.lang.Integer
属性值: 1

最终

到这边基本上就结束啦~
最后是最终版的代码

public class ObjectUtil {
    private static Map<Class<?>, Map<String, Field>> fieldCache = new HashMap<>();

    public static Result haveEmpty(Object object) {
        // 获取对象的 Class 属性
        Class<?> objectClass = object.getClass();

        Map<String, Field> classFieldCache = fieldCache.get(objectClass);

        // 如果缓存中不存在该类的字段信息,则进行反射获取并缓存起来
        if (classFieldCache == null) {
            classFieldCache = new HashMap<>();
            Field[] fields = objectClass.getDeclaredFields();
            for (Field field : fields) {
                // 设置属性可访问,即使是私有属性
                field.setAccessible(true);
                classFieldCache.put(field.getName(), field);
            }
            fieldCache.put(objectClass, classFieldCache);
        }

        // 遍历属性
        for(Field field : classFieldCache.values()) {
            String fieldName = field.getName();
            Class<?> fieldType = field.getType();

            try{
                Object fieldValue = field.get(object);
                /* 判空操作
                 * 使用 StringUtils 工具类或自定义的静态方法,避免直接调用 isEmpty() 方法,可以提高性能。
                 */
                if (String.class.equals(fieldType) && StringUtils.isEmpty(fieldValue)){
                    return Result.error(201,"字段:" + fieldName + "为空。");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return Result.ok("验证完毕,无空字符串");
    }
}
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以使用以下工具判断对象是否为空: ```java public class ObjectUtils { private ObjectUtils() {} /** * 判断对象是否为null */ public static boolean isNull(Object object) { return object == null; } /** * 判断对象是否不为null */ public static boolean isNotNull(Object object) { return !isNull(object); } /** * 判断对象是否为空,包括null、""、" " */ public static boolean isEmpty(Object object) { if (isNull(object)) { return true; } if (object instanceof CharSequence) { return ((CharSequence) object).length() == 0; } if (object instanceof Collection) { return ((Collection) object).isEmpty(); } if (object instanceof Map) { return ((Map) object).isEmpty(); } if (object instanceof Object[]) { Object[] objectArray = (Object[]) object; if (objectArray.length == 0) { return true; } boolean empty = true; for (Object obj : objectArray) { if (!isEmpty(obj)) { empty = false; break; } } return empty; } return false; } /** * 判断对象是否不为空,包括null、""、" " */ public static boolean isNotEmpty(Object object) { return !isEmpty(object); } } ``` 其,`isNull`方法用于判断对象是否为null,`isNotNull`方法用于判断对象是否不为null,`isEmpty`方法用于判断对象是否为空,包括null、""、" ",`isNotEmpty`方法用于判断对象是否不为空,包括null、""、" "。 ### 回答2: 判断对象为空的工具主要目的是判断一个对象是否为空,下面是一个简单实现的例子: ``` public class ObjectUtil { /** * 判断一个对象是否为空 * @param obj 待判断对象 * @return true表示对象为空,false表示对象不为空 */ public static boolean isEmpty(Object obj) { if (obj == null) { return true; } // 如果对象为字符串型,则判断字符串是否为空 if (obj instanceof String) { String str = (String) obj; return str.trim().length() == 0; } // 如果对象为数组型,则判断数组长度是否为0 if (obj.getClass().isArray()) { return Array.getLength(obj) == 0; } // 如果对象为集合型,则判断集合大小是否为0 if (obj instanceof Collection) { Collection<?> collection = (Collection<?>) obj; return collection.isEmpty(); } // 如果对象为Map型,则判断Map大小是否为0 if (obj instanceof Map) { Map<?, ?> map = (Map<?, ?>) obj; return map.isEmpty(); } return false; } } ``` 这个工具的`isEmpty`方法接收一个参数对象,通过判断对象型和属性判断是否为空。首先判断对象是否为null,若为null则返回true表示对象为空。接着判断对象型,如果是字符串型,则去除两端的空格后判断长度是否为0;如果是数组型,则判断数组长度是否为0;如果是集合型,则判断集合大小是否为0;如果是Map型,则判断Map大小是否为0。 ### 回答3: 判断对象为空的工具主要是为了方便开发人员在编写代码时能够快速、准确地判断一个对象是否为空,避免因为空指针而引发的异常。 工具的核心方法是isEmpty,其主要逻辑如下: 1. 首先,判断对象是否为null,如果是,则返回true,表示对象为空; 2. 其次,判断对象是否为字符串型,如果是,进一步判断是否为空字符串,如果是,则返回true,表示对象为空; 3. 如果对象不是null也不是字符串型,进一步判断其是否为集合型,如果是,判断是否为空集合,如果是,则返回true,表示对象为空; 4. 如果对象既不是null也不是字符串型也不是集合型,那么判断其是否为数组型,如果是,进一步判断其长度是否为0,如果是,则返回true,表示对象为空; 5. 如果以上都不满足,则返回false,表示对象不为空。 该工具还可以扩展其他的判断逻辑,例如判断数组、集合等对象的元素是否为空。 使用该工具可以简化代码,提高代码可读性和可维护性。例如,在进行对象判空时,只需要调用isEmpty方法即可,无需编写冗长的判断逻辑。同时,该工具还可以辅助编写单元测试,以确保对象判断为空的逻辑正确性。 总之,判断对象为空的工具开发具有较高的实用性和可扩展性,能够提高开发效率和代码质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值