看似很雞肋其實在某些特殊場景還是比較有用的。
比如你將實體類轉Map或者拿到一個Map結果的時候,你是怎麼獲取某個map的key和value。

方法一:
宣告 String key1="name"; key為 key1,value 為map.get(key1);
1         Map<String,Object> map=new HashMap<>();
2 map.put("aaa",1);
3
4 //獲取map的key 和value
5 //key 為key1
6 String key1="aaa";
7 //value 為 map.get(key1)
8 map.get(key1);


然後好像日常使用中也沒有其他的方法了,下面將帶來另外一種使用方法,話不多說直接上程式碼
  1 import java.io.Serializable;
2 import java.lang.annotation.ElementType;
3 import java.lang.annotation.Retention;
4 import java.lang.annotation.RetentionPolicy;
5 import java.lang.annotation.Target;
6 import java.lang.invoke.SerializedLambda;
7 import java.lang.reflect.Field;
8 import java.lang.reflect.InvocationTargetException;
9 import java.lang.reflect.Method;
10 import java.util.function.Function;
11
12 /**
13 * Java8通過Function函式獲取欄位名稱(獲取實體類的欄位名稱)
14 * @see ColumnUtil#main(java.lang.String[]) 使用示例
15 * @author jx
16 */
17 public class ColumnUtil {
18
19 /**
20 * 使Function獲取序列化能力
21 */
22 @FunctionalInterface
23 public interface SFunction<T, R> extends Function<T, R>, Serializable {
24 }
25
26 /**
27 * 欄位名註解,宣告表字段
28 */
29 @Target(ElementType.FIELD)
30 @Retention(RetentionPolicy.RUNTIME)
31 public @interface TableField {
32 String value() default "";
33 }
34
35 //預設配置
36 static String defaultSplit = "";
37 static Integer defaultToType = 0;
38
39 /**
40 * 獲取實體類的欄位名稱(實體宣告的欄位名稱)
41 */
42 public static <T> String getFieldName(SFunction<T, ?> fn) {
43 return getFieldName(fn, defaultSplit);
44 }
45
46 /**
47 * 獲取實體類的欄位名稱
48 * @param split 分隔符,多個字母自定義分隔符
49 */
50 public static <T> String getFieldName(SFunction<T, ?> fn, String split) {
51 return getFieldName(fn, split, defaultToType);
52 }
53
54 /**
55 * 獲取實體類的欄位名稱
56 * @param split 分隔符,多個字母自定義分隔符
57 * @param toType 轉換方式,多個字母以大小寫方式返回 0.不做轉換 1.大寫 2.小寫
58 */
59 public static <T> String getFieldName(SFunction<T, ?> fn, String split, Integer toType) {
60 SerializedLambda serializedLambda = getSerializedLambda(fn);
61
62 // 從lambda資訊取出method、field、class等
63 String fieldName = serializedLambda.getImplMethodName().substring("get".length());
64 fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
65 Field field;
66 try {
67 field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
68 } catch (ClassNotFoundException | NoSuchFieldException e) {
69 throw new RuntimeException(e);
70 }
71
72 // 從field取出欄位名,可以根據實際情況調整
73 TableField tableField = field.getAnnotation(TableField.class);
74 if (tableField != null && tableField.value().length() > 0) {
75 return tableField.value();
76 } else {
77
78 //0.不做轉換 1.大寫 2.小寫
79 switch (toType) {
80 case 1:
81 return fieldName.replaceAll("[A-Z]", split + "$0").toUpperCase();
82 case 2:
83 return fieldName.replaceAll("[A-Z]", split + "$0").toLowerCase();
84 default:
85 return fieldName.replaceAll("[A-Z]", split + "$0");
86 }
87
88 }
89
90 }
91
92 private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) {
93 // 從function取出序列化方法
94 Method writeReplaceMethod;
95 try {
96 writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
97 } catch (NoSuchMethodException e) {
98 throw new RuntimeException(e);
99 }
100
101 // 從序列化方法取出序列化的lambda資訊
102 boolean isAccessible = writeReplaceMethod.isAccessible();
103 writeReplaceMethod.setAccessible(true);
104 SerializedLambda serializedLambda;
105 try {
106 serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
107 } catch (IllegalAccessException | InvocationTargetException e) {
108 throw new RuntimeException(e);
109 }
110 writeReplaceMethod.setAccessible(isAccessible);
111 return serializedLambda;
112 }
113
114
115 /**
116 * 測試使用者實體類
117 */
118 public static class TestUserDemo implements Serializable {
119
120 private static final long serialVersionUID = 1L;
121
122 private String loginName;
123 private String name;
124 private String companySimpleName;
125
126 @ColumnUtil.TableField("nick")
127 private String nickName;
128
129 public String getLoginName() {
130 return loginName;
131 }
132
133 public void setLoginName(String loginName) {
134 this.loginName = loginName;
135 }
136
137 public String getNickName() {
138 return nickName;
139 }
140
141 public void setNickName(String nickName) {
142 this.nickName = nickName;
143 }
144
145 public static long getSerialVersionUID() {
146 return serialVersionUID;
147 }
148
149 public String getName() {
150 return name;
151 }
152
153 public void setName(String name) {
154 this.name = name;
155 }
156
157 public String getCompanySimpleName() {
158 return companySimpleName;
159 }
160
161 public void setCompanySimpleName(String companySimpleName) {
162 this.companySimpleName = companySimpleName;
163 }
164 }
165
166
167 /**
168 * 參考示例
169 */
170 public static void main(String[] args) {
171
172 //實體類原欄位名稱返回
173 System.out.println();
174 System.out.println("實體類原欄位名稱返回");
175 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getLoginName));
176 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getNickName));
177 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName));
178
179 System.out.println();
180 System.out.println("實體類欄位名稱增加分隔符");
181 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_"));
182
183 System.out.println();
184 System.out.println("實體類欄位名稱增加分隔符 + 大小寫");
185 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 0));
186 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 1));
187 System.out.println("欄位名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 2));
188
189
190 }
191
192
193 }