Java反射機制,如何將一個實體類所有字段賦值為null
將一個實體類所有字段賦值為null
起因
在我們想要使用一個實體類的時候,如果發(fā)現(xiàn)創(chuàng)建這個類的時候,給某一些字段設(shè)置了初始值(某些場景下的特殊需要),但我們這個時候又不需要這些初始化值的時候,我們就會想要把這些值全部清除掉,讓其變?yōu)橐粋€干凈的類,我們可以手動一個一個去賦null值,我一開始就是這么做的,同事看到后告訴我,你可以嘗試使用反射機制,自己封裝一個工具類,這樣大家都可以使用,于是我就這么做了,也就有了下面比較low B 的代碼:
我的代碼:
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); ? ? ? ? ? ? //將值設(shè)為null ? ? ? ? ? ? method.invoke(model, new Object[]{null}); ? ? ? ? } ? ? }
代碼寫完的那一刻,真的很爽,雖然這個東西比較簡單,但還是有一點成就感。然后告訴同事我寫好了,讓他幫忙優(yōu)化一下(畢竟他在我心里是一個真正的大牛),午休結(jié)束后,他發(fā)來了兩個方法給我,以不同的方式實現(xiàn),不過都是基于反射機制。以下是他的代碼:
第一種方法
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; ? ? }
第二種方法
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屬性置為““或者空值
工具類
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); ? ? ? ? ? ? ? ? ? ? ? ? //將值設(shè)為空串 ? ? ? ? ? ? ? ? ? ? ? ? method.invoke(o, ""); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? ? ? throw new RuntimeException(e); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return o; ? ? }? ? ? ? /** ? ? ?* 含遞歸 ? ? ?* 將實體類中的 String類型或?qū)ο?屬性為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); ? ? ? ? ? ? ? ? ? ? ? ? //將值設(shè)為空串 ? ? ? ? ? ? ? ? ? ? ? ? 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; ? ? } }
測試類
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);?? ? ? }? }
先創(chuàng)建需要的實體
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; ? ? } }
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; ? ? } }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié)
這篇文章主要介紹了關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05Java通過python命令執(zhí)行DataX任務(wù)的實例
今天小編就為大家分享一篇Java通過python命令執(zhí)行DataX任務(wù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08三種SpringBoot中實現(xiàn)異步調(diào)用的方法總結(jié)
Spring Boot 提供了多種方式來實現(xiàn)異步任務(wù),這篇文章主要為大家介紹了常用的三種實現(xiàn)方式,文中的示例代碼講解詳細,需要的可以參考一下2023-05-05java?freemarker實現(xiàn)動態(tài)生成excel文件
這篇文章主要為大家詳細介紹了java如何通過freemarker實現(xiàn)動態(tài)生成excel文件,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12Java 創(chuàng)建動態(tài)類和查看方法列表信息的實例
這篇文章主要介紹了 Java 創(chuàng)建動態(tài)類和查看方法列表信息的實例的相關(guān)資料,需要的朋友可以參考下2017-06-06