看似很鸡肋其实在某些特殊场景还是比较有用的。
比如你将实体类转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 }