摘要:很多開發場景需要用到的屬性名,直接寫死屬性名字符串的形式容易產生屬性名一旦變化,不會告訴你你的字符串需要同步修改。的可以通過方法引用簡化代碼,同樣也可以通過的方法引用拿到屬性名,避免潛在的。
很多開發場景需要用到Java Bean的屬性名,直接寫死屬性名字符串的形式容易產生bug(屬性名一旦變化,IDE不會告訴你你的字符串需要同步修改)。JDK8的Lambda可以通過方法引用簡化代碼,同樣也可以通過getter/setter的方法引用拿到屬性名,避免潛在的bug。期望實現效果
// 傳統方式:hard code寫死屬性名 // String ITEM_NAME = "orgName"; // 方法引用:替代hard code字符串,當屬性名變化時IDE會同步提示,避免未同步產生bug String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);具體實現代碼封裝 1. 定義FunctionalInterface 接收方法引用
/** * getter方法接口定義 */ @FunctionalInterface public interface IGetter2. 定義getter/setter引用轉換屬性名的工具類extends Serializable { Object apply(T source); } /** * setter方法接口定義 */ @FunctionalInterface public interface ISetter extends Serializable { void accept(T t, U u); }
public class BeanUtils { ... /** * 緩存類-Lambda的映射關系 */ private static Map3. 開心的引用CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>(); /*** * 轉換方法引用為屬性名 * @param fn * @return */ public static String convertToFieldName(IGetter fn) { SerializedLambda lambda = getSerializedLambda(fn); String methodName = lambda.getImplMethodName(); String prefix = null; if(methodName.startsWith("get")){ prefix = "get"; } else if(methodName.startsWith("is")){ prefix = "is"; } if(prefix == null){ log.warn("無效的getter方法: "+methodName); } // 截取get/is之后的字符串并轉換首字母為小寫(S為diboot項目的字符串工具類,可自行實現) return S.uncapFirst(S.substringAfter(methodName, prefix)); } /*** * 轉換setter方法引用為屬性名 * @param fn * @return */ public static String convertToFieldName(ISetter fn) { SerializedLambda lambda = getSerializedLambda(fn); String methodName = lambda.getImplMethodName(); if(!methodName.startsWith("set")){ log.warn("無效的setter方法: "+methodName); } // 截取set之后的字符串并轉換首字母為小寫(S為diboot項目的字符串工具類,可自行實現) return S.uncapFirst(S.substringAfter(methodName, "set")); } /*** * 獲取類對應的Lambda * @param fn * @return */ private static SerializedLambda getSerializedLambda(Serializable fn){ //先檢查緩存中是否已存在 SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass()); if(lambda == null){ try{//提取SerializedLambda并緩存 Method method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); lambda = (SerializedLambda) method.invoke(fn); CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda); } catch (Exception e){ log.error("獲取SerializedLambda異常, class="+fn.getClass().getSimpleName(), e); } } return lambda; } }
String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);
Diboot - 簡單高效的輕代碼開發框架
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74790.html
摘要:通過對返回字符串切片第位到倒數第位即可獲得對象的類型。測試對象是的深拷貝是的子集,不能表示中所有值。序列化結果是,對象序列化結果是日期字符串不能表示函數對象和只能序列化對象自有的可枚舉屬性。 對象 對象是JavaScript的基本數據類型:屬性的無序集合。每個屬性key: value和屬性描述符descripter組成。 屬性名key:字符串或合法的變量標識符; 屬性值value:...
摘要:有以下中方式可以使用和對象初始化器關鍵字使用關鍵字為屬性添加一個函數,函數名即為屬性名,函數不傳參,函數傳入的參數為設置對象的新值。需被定義或修改的屬性名。目前流行的框架的響應式系統就是利用設置來追蹤數據變化,從而導致視圖更新。 什么是getter 和 setter ? getter: 讀取對象屬性時將被調用的函數。setter:設置對象屬性時被調用的函數。 有以下4中方式可以使用 s...
摘要:在使用的過程中,通過操作符為對象添加新屬性是很常見的操作。但是,這個操作的結果實際上會受到原型鏈上的同名屬性影響。通過它,可以做到操作符做不到的事情,比如為對象設置一個新屬性,即使它的原型鏈上已經有一個的同名屬性。 在使用JavaScript的過程中,通過=操作符為對象添加新屬性是很常見的操作:obj.newProp = value;。但是,這個操作的結果實際上會受到原型鏈上的同名屬性...
摘要:所以,我實現了一個稱為的類來應用反射。現在流行的語言大都支持反射。這組內省主要是針對類進行操作的,能夠獲取類的屬性信息。可以看到,通過的內省機制,解決了的最關鍵的問題。在封裝反射的時候,會充分考慮到各種情況。 BeanMap 學習具體的技術工具的好辦法就是些Demo、造輪子。所以,我實現了一個稱為BeanMap的類來應用java反射API。 這個BeanMap的功能是將一個Bean包裝...
摘要:使用方法能以簡單的注解形式來簡化代碼,提高開發人員的開發效率。能通過注解的方式,在編譯時自動為屬性生成構造器方法。出現的神奇就是在源碼中沒有和方法,但是在編譯生成的字節碼文件中有和方法。沒法實現多種參數構造器的重載。 1 Lombok背景介紹 官方介紹如下: Project Lombok makes java a spicier language by addi...
閱讀 2721·2023-04-26 02:28
閱讀 2551·2021-09-27 13:36
閱讀 3123·2021-09-03 10:29
閱讀 2751·2021-08-26 14:14
閱讀 2101·2019-08-30 15:56
閱讀 830·2019-08-29 13:46
閱讀 2609·2019-08-29 13:15
閱讀 454·2019-08-29 11:29