在编码时经常会用到同名的属性名字符串,比如
-
用相同的属性名做为 map 中的键;
-
在 mybatis 中,根据属性名的下划线字符串来拼接 sql 查询条件。
需要修改属性名时,如果是用字符串硬编码的,引用的地方越多,修改越困难
但是如果用的是 java8 中的属性引用,操作起来就很方便了,修改一处即可修改全部相关引用。
参考下面测试类,怎样使用;
如果想要修改
articleName
为
articleTitle
,
在 IDEA 中,修改类的属性名很方便,选中属性名 articleName,按下快捷键 <Shift + F6>,键入新的属性名称 articleTitle,确认即可替换所有关联的属性名称
import
lombok
.
Getter
;
import
lombok
.
Setter
;
* 属性工具类测试
* @author lilou
public
class
FieldUtilTest
{
@Setter
@Getter
static
class
Article
{
String articleName
;
String articleContent
;
public
static
void
main
(
String
[
]
args
)
{
System
.
out
.
println
(
FieldUtil
.
noPrefix
(
Article
:
:
getArticleName
)
)
;
System
.
out
.
println
(
FieldUtil
.
underline
(
Article
:
:
getArticleName
)
)
;
System
.
out
.
println
(
FieldUtil
.
underlineUpper
(
Article
:
:
getArticleContent
)
)
;
System
.
out
.
println
(
FieldUtil
.
toSymbolCase
(
Article
:
:
getArticleName
,
'$'
)
)
;
System
.
out
.
println
(
FieldUtil
.
noPrefix
(
Article
:
:
setArticleName
)
)
;
System
.
out
.
println
(
FieldUtil
.
underline
(
Article
:
:
setArticleName
)
)
;
System
.
out
.
println
(
FieldUtil
.
underlineUpper
(
Article
:
:
setArticleContent
)
)
;
System
.
out
.
println
(
FieldUtil
.
toSymbolCase
(
Article
:
:
setArticleName
,
'$'
)
)
;
关键逻辑是利用了 java8 中的 SerializedLambda 的 getImplMethodName 方法来获取属性名。
源码中引用了 hutool 第三方工具类的
StrUtil
工具,方便操作字符串,当然也可自行开发。
参考资料:
利用 Lambda 实现通过 getter/setter 方法引用拿到属性名 - SegmentFault 思否
import
cn
.
hutool
.
core
.
util
.
StrUtil
;
import
java
.
io
.
Serializable
;
import
java
.
lang
.
invoke
.
SerializedLambda
;
import
java
.
lang
.
reflect
.
Method
;
* 属性工具类,用来获取 Getter 和 Setter 属性的名称。支持首字母小写样式,下划线的样式和自定义样式
* 参考:[利用Lambda实现通过getter/setter方法引用拿到属性名 - SegmentFault 思否](https://segmentfault.com/a/1190000019389160)
* @author lilou
public
class
FieldUtil
{
* ===========> getter 方法引用 <===========
* 下划线样式,小写
public
static
<
T
>
String
underline
(
IGetter
<
T
>
fn
)
{
return
toSymbolCase
(
fn
,
'_'
)
;
* 下划线样式,大写
public
static
<
T
>
String
underlineUpper
(
IGetter
<
T
>
fn
)
{
return
underline
(
fn
)
.
toUpperCase
(
)
;
* 依据符号转换样式
public
static
<
T
>
String
toSymbolCase
(
IGetter
<
T
>
fn
,
char
symbol
)
{
return
StrUtil
.
toSymbolCase
(
noPrefix
(
fn
)
,
symbol
)
;
* 转换getter方法引用为属性名,首字母小写
public
static
<
T
>
String
noPrefix
(
IGetter
<
T
>
fn
)
{
return
getGeneralField
(
fn
)
;
* ===========> setter 方法引用 <===========
* 下划线样式,小写
public
static
<
T
,
R
>
String
underline
(
ISetter
<
T
,
R
>
fn
)
{
return
toSymbolCase
(
fn
,
'_'
)
;
* 下划线样式,大写
public
static
<
T
,
R
>
String
underlineUpper
(
ISetter
<
T
,
R
>
fn
)
{
return
underline
(
fn
)
.
toUpperCase
(
)
;
* 依据符号转换样式
public
static
<
T
,
R
>
String
toSymbolCase
(
ISetter
<
T
,
R
>
fn
,
char
symbol
)
{
return
StrUtil
.
toSymbolCase
(
noPrefix
(
fn
)
,
symbol
)
;
* 转换setter方法引用为属性名,首字母小写
public
static
<
T
,
R
>
String
noPrefix
(
ISetter
<
T
,
R
>
fn
)
{
return
getGeneralField
(
fn
)
;
* ===========> 复用功能 <===========
* 获得set或get或is方法对应的标准属性名,其它前缀的方法名使用原名
private
static
String
getGeneralField
(
Serializable fn
)
{
SerializedLambda lambda
=
getSerializedLambda
(
fn
)
;
String getOrSetMethodName
=
lambda
.
getImplMethodName
(
)
;
final
String generalField
=
StrUtil
.
getGeneralField
(
getOrSetMethodName
)
;
return
StrUtil
.
isEmpty
(
generalField
)
?
getOrSetMethodName
:
generalField
;
* 获取类对应的Lambda
private
static
SerializedLambda
getSerializedLambda
(
Serializable fn
)
{
SerializedLambda lambda
;
try
{
Method method
=
fn
.
getClass
(
)
.
getDeclaredMethod
(
"writeReplace"
)
;
method
.
setAccessible
(
Boolean
.
TRUE
)
;
lambda
=
(
SerializedLambda
)
method
.
invoke
(
fn
)
;
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
"获取SerializedLambda异常, class="
+
fn
.
getClass
(
)
.
getSimpleName
(
)
,
e
)
;
return
lambda
;
* getter方法接口定义
@FunctionalInterface
public
interface
IGetter
<
T
>
extends
Serializable
{
Object
apply
(
T source
)
;
* setter方法接口定义
@FunctionalInterface
public
interface
ISetter
<
T
,
U
>
extends
Serializable
{
void
accept
(
T t
,
U u
)
;
背景在编码时经常会用到同名的属性名字符串,比如用相同的属性名做为 map 中的键;在 mybatis 中,根据属性名的下划线字符串来拼接 sql 查询条件。需要修改属性名时,如果是用字符串硬编码的,引用的地方越多,修改越困难但是如果用的是 java8 中的属性引用,操作起来就很方便了,修改一处即可修改全部相关引用。属性工具类测试参考下面测试类,怎样使用;如果想要修改 articleName 为 articleTitle,在 IDEA 中,修改类的属性名很方便,选中属性名 articl
在我们
开发
过程中常常有一个需求,就是要知道实体类中Getter方法对应的
属性
名
称(Field Name),例如实体类
属性
到数据库字段的映射,我们常常是硬编码指定
属性
名
,这种硬编码有两个缺点。
1、编码效率低:因为要硬编码写
属性
名
,很可能写错,需要非常小心,时间浪费在了不必要的检查上。
2、容易让
开发
人员踩坑:例如有一天发现实体类中Field Name定义的不够明确,希望换一个Field Name...
package cn.com.hisserver.util;
import
java
.lang.reflect.Field;
import
java
.lang.reflect.Method;
import
java
.util.ArrayList;
import
java
.util.HashMap;
import
java
.util.List;
import
java
.
Java
实体转换的
工具类
主要是用来方便地进行不同实体类之间的转换操作。在
开发
过程中,我们通常会涉及到不同层之间的数据传递,比如数据库实体类与前端展示实体类之间的转换,或者接口请求实体类与数据库实体类之间的转换等。
这些实体类之间的
属性
可能会存在一些差异,比如
属性
名
不一致、
属性
类型不一致等,因此需要编写一些代码来手动进行
属性
的赋值,这样就会导致代码冗长且容易出错。而使用
Java
实体转换的
工具类
就可以简化这个过程,并提高代码的可读性和可维护性。
一个常用的
Java
实体转换
工具类
是Apache Commons BeanUtils。它提供了一系列
工具
方法来实现不同实体类之间的复制
属性
、
获取
属性
值等操作。我们可以通过该
工具类
实现从源实体对象向目标实体对象的
属性
赋值,无需手动编写大量的赋值代码,提高了
开发
效率。
除了BeanUtils,还有其他一些类似的
Java
实体转换
工具类
,比如Spring Framework中的BeanUtils,Spring Boot中的ModelMapper等,它们都提供了简单易用的方法来进行实体转换操作。
总之,
Java
实体转换的
工具类
能够帮助我们简化实体类之间的转换操作,减少冗余代码,提高代码的可读性和可维护性。在实际
开发
中,选择一个合适的
工具类
来进行实体转换是非常重要的。