服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Java反射机制,如何将一个实体类所有字段赋值为null

Java反射机制,如何将一个实体类所有字段赋值为null

2022-08-14 09:52Robot Java教程

这篇文章主要介绍了Java反射机制,如何将一个实体类所有字段赋值为null,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

将一个实体类所有字段赋值为null

起因

在我们想要使用一个实体类的时候,如果发现创建这个类的时候,给某一些字段设置了初始值(某些场景下的特殊需要),但我们这个时候又不需要这些初始化值的时候,我们就会想要把这些值全部清除掉,让其变为一个干净的类,我们可以手动一个一个去赋null值,我一开始就是这么做的,同事看到后告诉我,你可以尝试使用反射机制,自己封装一个工具类,这样大家都可以使用,于是我就这么做了,也就有了下面比较low B 的代码:

我的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void reflectClassValueToNull(Object model) throws Exception {        
        //获取此类的所有父类
        List<Class<?>> listSuperClass = Lists.newArrayList();
        Class<?> superclass = model.getClass().getSuperclass();
        while (superclass != null) {
            if (superclass.getName().equals("java.lang.Object")) {
                break;
            }
            listSuperClass.add(superclass);
            superclass = superclass.getSuperclass();
        }
        //遍历处理所有父类的字段
        for (Class<?> clazz : listSuperClass) {
            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                String name = fields[i].getName();
                Class type = fields[i].getType();
                Method method = clazz.getMethod("set" + name.replaceFirst(name.substring(0, 1),
                        name.substring(0, 1).toUpperCase()), type);
                method.invoke(model, new Object[]{null});
            }
        }
        //处理此类自己的字段
        Field[] fields = model.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            String name = fields[i].getName();
            Class type = fields[i].getType();
            //获取属性的set方法
            Method method = model.getClass().getMethod("set" + name.replaceFirst(name.substring(0, 1),
                    name.substring(0, 1).toUpperCase()), type);
            //将值设为null
            method.invoke(model, new Object[]{null});
        }
    }

代码写完的那一刻,真的很爽,虽然这个东西比较简单,但还是有一点成就感。然后告诉同事我写好了,让他帮忙优化一下(毕竟他在我心里是一个真正的大牛),午休结束后,他发来了两个方法给我,以不同的方式实现,不过都是基于反射机制。以下是他的代码:

第一种方法

?
1
2
3
4
5
6
7
8
9
10
public static <T> T byMethod(T t) {
        ReflectionUtils.getAllMethods(t.getClass(), method -> Objects.requireNonNull(method).getName().indexOf("set") == 0).forEach(method -> {
            try {
                method.invoke(t, new Object[]{null});
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        });
        return t;
    }

第二种方法

?
1
2
3
4
5
6
7
8
9
10
11
public static <T> T byField(T t) {
        ReflectionUtils.getAllFields(t.getClass()).forEach(field -> {
            try {
                field.setAccessible(true);
                field.set(t, null);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
        return t;
    }

所以,差距你们看到了吗?反正我看到了!

将实体类中的null属性置为““或者空值

工具类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.chryl.util; 
import java.lang.reflect.Field;
import java.lang.reflect.Method; 
public class ReflectionUtils { 
    /**
     * 将实体类中的String类型属性为null的置为""
     *
     * @param o
     * @return
     */
    public static Object nullifyStrings(Object o) {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field f : declaredFields) {
            f.setAccessible(true);
            String name = f.getName();
            if ("serialVersionUID".equals(name)) {
                continue;
            }
            //获取属性类型
            Class type = f.getType();
            try {
                //只操作String类型
                if (type.equals(String.class)) {
                    String value = (String) f.get(o);
                    //如果为空
                    if (value == null || value.trim().isEmpty()) {
                        //获取属性的set方法
                        Method method = o.getClass().getMethod("set" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase()), type);
//                        f.set(o, null);
                        //将值设为空串
                        method.invoke(o, "");
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return o;
   
 
    /**
     * 含递归
     * 将实体类中的 String类型或对象 属性为null的置为""或空对象
     *
     * @param o
     * @return
     */
    public static Object nullifyObjectOrStrings(Object o) throws ClassNotFoundException {
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field f : declaredFields) {
            f.setAccessible(true);
            String name = f.getName();
            if ("serialVersionUID".equals(name)) {
                continue;
            }
 
            //获取属性类型
            Class type = f.getType();
            try {
                //获取属性的set方法
                String setterMethod = "set" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
                Method method = o.getClass().getMethod(setterMethod, type);
                //只操作String类型
                if (type.equals(String.class)) {
                    String value = (String) f.get(o);
                    //如果为空
                    if (value == null || value.trim().isEmpty()) {
//                        f.set(o, null);
                        //将值设为空串
                        method.invoke(o, "");
                    }
                } else {
                    Class<?> aClass = Class.forName(f.getGenericType().getTypeName());
                    Object createObj = aClass.newInstance();
                    //实体赋值
                    method.invoke(o, createObj);
                    nullifyObjectOrStrings(createObj);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return o;
    }
}

测试类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.chryl.test;  
import com.chryl.entity.User;
import com.chryl.util.ReflectionUtils;
 
/**
 * Created By Chryl on 2021-08-11.
 */
public class NullStrTest {
    public static void main(String[] args) throws Exception { 
        User user = new User();
        User user1 = (User) ReflectionUtils.nullifyStrings(user);
        System.out.println(user1); 
        User user12 = (User) ReflectionUtils.nullifyObjectOrStrings(user);
        System.out.println(user12);  
   
}

先创建需要的实体

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.chryl.entity; 
import java.io.Serializable; 
/**
 * Created By Chryl on 2021-08-11.
 */
public class User implements Serializable {
    private static final long serialVersionUID = 930878416859194735L; 
    private String username;
    private String password;
    private String age;
    private ParamsList paramsList; 
    public User() {
    }
 
    public User(String username, String password, String age) {
        this.username = username;
        this.password = password;
        this.age = age;
    }
 
    public User(String username, String password, String age, ParamsList paramsList) {
        this.username = username;
        this.password = password;
        this.age = age;
        this.paramsList = paramsList;
    }
 
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }
 
    public String getUsername() {
        return username;
    }
 
    public void setUsername(String username) {
        this.username = username;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
 
    public String getAge() {
        return age;
    }
 
    public void setAge(String age) {
        this.age = age;
    }
 
    public ParamsList getParamsList() {
        return paramsList;
    }
 
    public void setParamsList(ParamsList paramsList) {
        this.paramsList = paramsList;
    }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.chryl.entity; 
/**
 * Created By Chryl on 2021-08-12.
 */
public class ParamsList {
    private String param1;
    private String param2;
    private String param3;
    private String param4; 
    public ParamsList() {
    }
 
    public ParamsList(String param1, String param2, String param3, String param4) {
        this.param1 = param1;
        this.param2 = param2;
        this.param3 = param3;
        this.param4 = param4;
    }
 
    public String getParam1() {
        return param1;
    }
 
    public void setParam1(String param1) {
        this.param1 = param1;
    }
 
    public String getParam2() {
        return param2;
    }
 
    public void setParam2(String param2) {
        this.param2 = param2;
    }
 
    public String getParam3() {
        return param3;
    }
 
    public void setParam3(String param3) {
        this.param3 = param3;
    }
 
    public String getParam4() {
        return param4;
    }
 
    public void setParam4(String param4) {
        this.param4 = param4;
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。

原文链接:https://segmentfault.com/a/1190000012707351

延伸 · 阅读

精彩推荐