Java8通过Function获取字段名(获取实体类的字段名称)
看似很鸡肋其实在某些特殊场景还是比较有用的。
比如你将实体类转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 }
Java8通过Function获取字段名(获取实体类的字段名称)的更多相关文章
- c# 反射得到实体类的字段名称和值,DataTable转List<T>
/// <summary> /// 反射得到实体类的字段名称和值 /// var dict = GetProperties(model); /// </summary> /// ...
- MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致
MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致 使用ResultMap节点配置信息 在映射文件中 ...
- java 获取实体类对象属性值的方法
在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...
- C#、Python中分别是怎么实现通过字符串获取实体类的值以及给实体类赋值
一.引入 最近遇到一个项目里面的功能,在给实体类赋值的时候,由于赋值字段是动态生成的,所以如果用常用的方法(直接实体类的名称.字段名=要赋的值),将会生成很多无用的代码,所以找到了一个通过反射的赋值与 ...
- 通用maper无法获取实体类com.qmtt.model.PhWxUser对应的表名问题
spring boot在采用了热加载后,可能会出现“无法获取实体类com.qmtt.model.PhWxUser对应的表名!”的异常, 解决办法 在resources新建一个文件夹META-INF,新 ...
- C#获取EF实体对象或自定义属性类的字段名称和值
在年前上班的时候遇到了一个问题是这样描述的:我前台设计一个页面,是标签和文本框,当用户修改了哪个文本框的值,将该修改前的值.修改后的值,该值对应的字段,该值对应的行id获取到保存到数据库的某张表里.现 ...
- Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)
反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强 ...
- 反射中的 Method 的 getReadMethod 与 getWriteMethod 使用 【获取一个对象的所有属性字段名称和其对应的值】
转: class反射(一),以及Method 的 getReadMethod 与 getWriteMethod 使用 2018年11月28日 17:27:42 zich77521 阅读数 788 ...
- Sql中获取表结构(字段名称,类型,长度,说明)
Sql中获取表结构(字段名称,类型,长度,说明) SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Descript ...
随机推荐
- C++智能指针的原理和实现
一.智能指针起因 在C++中,动态内存的管理是由程序员自己申请和释放的,用一对运算符完成:new和delete. new:在动态内存中为对象分配一块空间并返回一个指向该对象的指针: delete:指向 ...
- react的每个方法为什么一定要bind this
一开始学习react的时候就了解了react的每个方法都要bind(this)或者使用箭头函数绑定this的指向,到底是为什么要这么写呢,当时要学习的东西太多了就没在意,今天特别好奇(不搞懂不吃饭的态 ...
- js函数和封装
$就是jquery对象,$()就是jQuery(),在里面可以传参数,作用就是获取元素 js对象与jQuery对象的区别:jQuery对象是一个数组,jQuery对象转为js对象:[0] 取第一个即可 ...
- Kickstart部署之FTP架构
原文转自:https://www.cnblogs.com/itzgr/p/10029551.html作者:木二 目录 一 准备 1.1 完整架构:Kickstart+DHCP+VSFTP+TFTP+P ...
- APMserv 5.2.6 安装教程
1.下载APMServ5.2.6.rar压缩包后解压,得到文件APMServ5.1.2.exe,其余两个没什么大用,APMServ解压缩说明.txt可以看一下,里面详细介绍了APMServ的功能和注意 ...
- centos7 netstat
netstat 是控制台命令,它可以显示路由表.实际的网络连接以及每一个网络接口设备的状态信息.Netstat 用于显示与 IP . TCP . UDP 和 ICMP 协议相关的统计数据,一般用于检验 ...
- Qt5之坐标系统
窗口坐标为逻辑坐标,是基于视口坐标系的. 视口坐标为物理坐标,是基于绘图设备坐标系的 窗口坐标始终以视口坐标为最终目标进行映射: QPainter::setWindow 修改了窗口位置和大小(左上角重 ...
- 存储系统管理(二)——Linux系统的swap分区、磁盘加密、磁盘阵列
磁盘驱动器上的空间 , 用作当前未使用部分内存的溢出.这样 , 系统就能在主内存中留出空间用于储存当前正在处理的数据 , 并在系统面临主内存空间不足的风险时提供应急溢出. swap分区的建立: fdi ...
- 基于Linux系统的MariaDB数据库的安装配置
数据库是指长期存储在计算机内.有组织的和可共享的数据集合.表是数据库存储数据的基本单位,一个表由若干个字段组成 MariaDB 数据库管理系统是 MySQL 的一个分支,主要由开源社区在维护,采用 G ...
- vue 嵌入倒计时组件( 亲测可用 )
由于花费了我不少时间才找到的组件,所以记录一下,后面方便自己好找一些,也算是分享出来给各位前端一起用. npm 下载npm install vue2-flip-countdown --save tem ...