<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在我們想要使用一個實體類的時候,如果發現建立這個類的時候,給某一些欄位設定了初始值(某些場景下的特殊需要),但我們這個時候又不需要這些初始化值的時候,我們就會想要把這些值全部清除掉,讓其變為一個乾淨的類,我們可以手動一個一個去賦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); //將值設為null method.invoke(model, new Object[]{null}); } }
程式碼寫完的那一刻,真的很爽,雖然這個東西比較簡單,但還是有一點成就感。然後告訴同事我寫好了,讓他幫忙優化一下(畢竟他在我心裡是一個真正的大牛),午休結束後,他發來了兩個方法給我,以不同的方式實現,不過都是基於反射機制。以下是他的程式碼:
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; }
所以,差距你們看到了嗎?反正我看到了!
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; } }
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); } }
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; } }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45