好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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测试数据/a/1190000012707351

查看更多关于Java反射机制,如何将一个实体类所有字段赋值为null的详细内容...

  阅读:25次