Java8通過Function獲取字段名的方法(獲取實體類的字段名稱)
看似很雞肋其實在某些特殊場景還是比較有用的。
比如你將實體類轉(zhuǎn)Map或者拿到一個Map結(jié)果的時候,你是怎么獲取某個map的key和value。
方法一:
聲明 String key1="aaa"; key為 key1,value 為map.get(key1);
Map<String,Object> map=new HashMap<>(); map.put("aaa",1); //獲取map的key 和value //key 為key1 String key1="aaa"; //value 為 map.get(key1) map.get(key1);
然后好像日常使用中也沒有其他的方法了,下面將帶來另外一種使用方法,話不多說直接上代碼[/code]
import java.io.Serializable; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.invoke.SerializedLambda; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.function.Function; /** * Java8通過Function函數(shù)獲取字段名稱(獲取實體類的字段名稱) * @see ColumnUtil#main(java.lang.String[]) 使用示例 * @author jx */ public class ColumnUtil { /** * 使Function獲取序列化能力 */ @FunctionalInterface public interface SFunction<T, R> extends Function<T, R>, Serializable { } /** * 字段名注解,聲明表字段 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface TableField { String value() default ""; } //默認配置 static String defaultSplit = ""; static Integer defaultToType = 0; /** * 獲取實體類的字段名稱(實體聲明的字段名稱) */ public static <T> String getFieldName(SFunction<T, ?> fn) { return getFieldName(fn, defaultSplit); } /** * 獲取實體類的字段名稱 * @param split 分隔符,多個字母自定義分隔符 */ public static <T> String getFieldName(SFunction<T, ?> fn, String split) { return getFieldName(fn, split, defaultToType); } /** * 獲取實體類的字段名稱 * @param split 分隔符,多個字母自定義分隔符 * @param toType 轉(zhuǎn)換方式,多個字母以大小寫方式返回 0.不做轉(zhuǎn)換 1.大寫 2.小寫 */ public static <T> String getFieldName(SFunction<T, ?> fn, String split, Integer toType) { SerializedLambda serializedLambda = getSerializedLambda(fn); // 從lambda信息取出method、field、class等 String fieldName = serializedLambda.getImplMethodName().substring("get".length()); fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase()); Field field; try { field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName); } catch (ClassNotFoundException | NoSuchFieldException e) { throw new RuntimeException(e); } // 從field取出字段名,可以根據(jù)實際情況調(diào)整 TableField tableField = field.getAnnotation(TableField.class); if (tableField != null && tableField.value().length() > 0) { return tableField.value(); } else { //0.不做轉(zhuǎn)換 1.大寫 2.小寫 switch (toType) { case 1: return fieldName.replaceAll("[A-Z]", split + "$0").toUpperCase(); case 2: return fieldName.replaceAll("[A-Z]", split + "$0").toLowerCase(); default: return fieldName.replaceAll("[A-Z]", split + "$0"); } } } private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) { // 從function取出序列化方法 Method writeReplaceMethod; try { writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace"); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } // 從序列化方法取出序列化的lambda信息 boolean isAccessible = writeReplaceMethod.isAccessible(); writeReplaceMethod.setAccessible(true); SerializedLambda serializedLambda; try { serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } writeReplaceMethod.setAccessible(isAccessible); return serializedLambda; } /** * 測試用戶實體類 */ public static class TestUserDemo implements Serializable { private static final long serialVersionUID = 1L; private String loginName; private String name; private String companySimpleName; @ColumnUtil.TableField("nick") private String nickName; public String getLoginName() { return loginName; } public void setLoginName(String loginName) { this.loginName = loginName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public static long getSerialVersionUID() { return serialVersionUID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCompanySimpleName() { return companySimpleName; } public void setCompanySimpleName(String companySimpleName) { this.companySimpleName = companySimpleName; } } /** * 參考示例 */ public static void main(String[] args) { //實體類原字段名稱返回 System.out.println(); System.out.println("實體類原字段名稱返回"); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getLoginName)); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getNickName)); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName)); System.out.println(); System.out.println("實體類字段名稱增加分隔符"); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_")); System.out.println(); System.out.println("實體類字段名稱增加分隔符 + 大小寫"); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 0)); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 1)); System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 2)); } }
輸出結(jié)果:
到此這篇關(guān)于Java8通過Function獲取字段名(獲取實體類的字段名稱)的文章就介紹到這了,更多相關(guān)Java8通過Function獲取字段名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
classloader類加載器_基于java類的加載方式詳解
下面小編就為大家?guī)硪黄猚lassloader類加載器_基于java類的加載方式詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10MyBatis實現(xiàn)多表聯(lián)合查詢resultType的返回值
這篇文章主要介紹了MyBatis多表聯(lián)合查詢resultType的返回值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03RocketMQ生產(chǎn)者調(diào)用start發(fā)送消息原理示例
這篇文章主要為大家介紹了RocketMQ生產(chǎn)者調(diào)用start發(fā)送消息原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11詳解Java如何在Array和List之間進行轉(zhuǎn)換
這篇文章主要為大家介紹了詳解Java如何在Array和List之間進行轉(zhuǎn)換的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05使用kafka-console-consumer.sh不停報WARN的問題及解決
這篇文章主要介紹了使用kafka-console-consumer.sh不停報WARN的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序,結(jié)合具體實例形式分析了java樹形選擇排序的原理、實現(xiàn)技巧與相關(guān)注意事項,需要的朋友可以參考下2017-05-05