Java8通過Function獲取字段名的方法(獲取實(shí)體類的字段名稱)
看似很雞肋其實(shí)在某些特殊場景還是比較有用的。
比如你將實(shí)體類轉(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ù)獲取字段名稱(獲取實(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 "";
}
//默認(rèn)配置
static String defaultSplit = "";
static Integer defaultToType = 0;
/**
* 獲取實(shí)體類的字段名稱(實(shí)體聲明的字段名稱)
*/
public static <T> String getFieldName(SFunction<T, ?> fn) {
return getFieldName(fn, defaultSplit);
}
/**
* 獲取實(shí)體類的字段名稱
* @param split 分隔符,多個字母自定義分隔符
*/
public static <T> String getFieldName(SFunction<T, ?> fn, String split) {
return getFieldName(fn, split, defaultToType);
}
/**
* 獲取實(shí)體類的字段名稱
* @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ù)實(shí)際情況調(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;
}
/**
* 測試用戶實(shí)體類
*/
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) {
//實(shí)體類原字段名稱返回
System.out.println();
System.out.println("實(shí)體類原字段名稱返回");
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("實(shí)體類字段名稱增加分隔符");
System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_"));
System.out.println();
System.out.println("實(shí)體類字段名稱增加分隔符 + 大小寫");
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獲取字段名(獲取實(shí)體類的字段名稱)的文章就介紹到這了,更多相關(guān)Java8通過Function獲取字段名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
classloader類加載器_基于java類的加載方式詳解
下面小編就為大家?guī)硪黄猚lassloader類加載器_基于java類的加載方式詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
MyBatis實(shí)現(xiàn)多表聯(lián)合查詢resultType的返回值
這篇文章主要介紹了MyBatis多表聯(lián)合查詢resultType的返回值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
RocketMQ生產(chǎn)者調(diào)用start發(fā)送消息原理示例
這篇文章主要為大家介紹了RocketMQ生產(chǎn)者調(diào)用start發(fā)送消息原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
詳解Java如何在Array和List之間進(jìn)行轉(zhuǎn)換
這篇文章主要為大家介紹了詳解Java如何在Array和List之間進(jìn)行轉(zhuǎn)換的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
VsCode配置java環(huán)境的詳細(xì)圖文教程
vscode是一個免費(fèi)的代碼編輯器,支持多種主題,應(yīng)用起來簡單方便,下面這篇文章主要給大家介紹了關(guān)于VsCode配置java環(huán)境的詳細(xì)圖文教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02
SpringIOC DI循環(huán)依賴實(shí)例詳解
這篇文章主要介紹了SpringIOC——DI循環(huán)依賴,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
使用kafka-console-consumer.sh不停報WARN的問題及解決
這篇文章主要介紹了使用kafka-console-consumer.sh不停報WARN的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序詳解
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)排序算法之樹形選擇排序,結(jié)合具體實(shí)例形式分析了java樹形選擇排序的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-05-05

