资讯专栏INFORMATION COLUMN

利用Lambda实现通过getter/setter方法引用拿到属性名

MingjunYang / 972人阅读

摘要:很多开发场景需要用到的属性名,直接写死属性名字符串的形式容易产生属性名一旦变化,不会告诉你你的字符串需要同步修改。的可以通过方法引用简化代码,同样也可以通过的方法引用拿到属性名,避免潜在的。

很多开发场景需要用到Java Bean的属性名,直接写死属性名字符串的形式容易产生bug(属性名一旦变化,IDE不会告诉你你的字符串需要同步修改)。JDK8的Lambda可以通过方法引用简化代码,同样也可以通过getter/setter的方法引用拿到属性名,避免潜在的bug。
期望实现效果
// 传统方式:hard code写死属性名
// String ITEM_NAME = "orgName";
// 方法引用:替代hard code字符串,当属性名变化时IDE会同步提示,避免未同步产生bug
String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);
具体实现代码封装 1. 定义FunctionalInterface 接收方法引用
/**
 * getter方法接口定义
 */
@FunctionalInterface
public interface IGetter extends Serializable {
    Object apply(T source);
}
/**
 * setter方法接口定义
 */
@FunctionalInterface
public interface ISetter extends Serializable {
    void accept(T t, U u);
}
2. 定义getter/setter引用转换属性名的工具类
public class BeanUtils {
    ...
    /**
     * 缓存类-Lambda的映射关系
     */
    private static Map CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();

    /***
     * 转换方法引用为属性名
     * @param fn
     * @return
     */
    public static  String convertToFieldName(IGetter fn) {
        SerializedLambda lambda = getSerializedLambda(fn);
        String methodName = lambda.getImplMethodName();
        String prefix = null;
        if(methodName.startsWith("get")){
            prefix = "get";
        }
        else if(methodName.startsWith("is")){
            prefix = "is";
        }
        if(prefix == null){
            log.warn("无效的getter方法: "+methodName);
        }
        // 截取get/is之后的字符串并转换首字母为小写(S为diboot项目的字符串工具类,可自行实现)
        return S.uncapFirst(S.substringAfter(methodName, prefix));
    }
    
    /***
     * 转换setter方法引用为属性名
     * @param fn
     * @return
     */
    public static  String convertToFieldName(ISetter fn) {
        SerializedLambda lambda = getSerializedLambda(fn);
        String methodName = lambda.getImplMethodName();
        if(!methodName.startsWith("set")){
            log.warn("无效的setter方法: "+methodName);
        }
        // 截取set之后的字符串并转换首字母为小写(S为diboot项目的字符串工具类,可自行实现)
        return S.uncapFirst(S.substringAfter(methodName, "set"));
    }
    
    /***
     * 获取类对应的Lambda
     * @param fn
     * @return
     */
    private static SerializedLambda getSerializedLambda(Serializable fn){
        //先检查缓存中是否已存在
        SerializedLambda lambda = CLASS_LAMDBA_CACHE.get(fn.getClass());
        if(lambda == null){
            try{//提取SerializedLambda并缓存
                Method method = fn.getClass().getDeclaredMethod("writeReplace");
                method.setAccessible(Boolean.TRUE);
                lambda = (SerializedLambda) method.invoke(fn);
                CLASS_LAMDBA_CACHE.put(fn.getClass(), lambda);
            }
            catch (Exception e){
                log.error("获取SerializedLambda异常, class="+fn.getClass().getSimpleName(), e);
            }
        }
        return lambda;
    }
}
3. 开心的引用
String ITEM_NAME = BeanUtils.convertToFieldName(User::getOrgName);

Diboot - 简单高效的轻代码开发框架

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74790.html

相关文章

  • JavaScript || 对象

    摘要:通过对返回字符串切片第位到倒数第位即可获得对象的类型。测试对象是的深拷贝是的子集,不能表示中所有值。序列化结果是,对象序列化结果是日期字符串不能表示函数对象和只能序列化对象自有的可枚举属性。 对象 对象是JavaScript的基本数据类型:属性的无序集合。每个属性key: value和属性描述符descripter组成。 属性名key:字符串或合法的变量标识符; 属性值value:...

    lavor 评论0 收藏0
  • 有关gettersetter的使用

    摘要:有以下中方式可以使用和对象初始化器关键字使用关键字为属性添加一个函数,函数名即为属性名,函数不传参,函数传入的参数为设置对象的新值。需被定义或修改的属性名。目前流行的框架的响应式系统就是利用设置来追踪数据变化,从而导致视图更新。 什么是getter 和 setter ? getter: 读取对象属性时将被调用的函数。setter:设置对象属性时被调用的函数。 有以下4中方式可以使用 s...

    SunZhaopeng 评论0 收藏0
  • 【js细节剖析】通过"="操作符为对象添加新属性时,结果会受到原型链上的同属性

    摘要:在使用的过程中,通过操作符为对象添加新属性是很常见的操作。但是,这个操作的结果实际上会受到原型链上的同名属性影响。通过它,可以做到操作符做不到的事情,比如为对象设置一个新属性,即使它的原型链上已经有一个的同名属性。 在使用JavaScript的过程中,通过=操作符为对象添加新属性是很常见的操作:obj.newProp = value;。但是,这个操作的结果实际上会受到原型链上的同名属性...

    wemallshop 评论0 收藏0
  • 封装BeanMap以及java的反射和内省

    摘要:所以,我实现了一个称为的类来应用反射。现在流行的语言大都支持反射。这组内省主要是针对类进行操作的,能够获取类的属性信息。可以看到,通过的内省机制,解决了的最关键的问题。在封装反射的时候,会充分考虑到各种情况。 BeanMap 学习具体的技术工具的好办法就是些Demo、造轮子。所以,我实现了一个称为BeanMap的类来应用java反射API。 这个BeanMap的功能是将一个Bean包装...

    张巨伟 评论0 收藏0
  • Lombok介绍、使用方法和总结

    摘要:使用方法能以简单的注解形式来简化代码,提高开发人员的开发效率。能通过注解的方式,在编译时自动为属性生成构造器方法。出现的神奇就是在源码中没有和方法,但是在编译生成的字节码文件中有和方法。没法实现多种参数构造器的重载。 1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by addi...

    30e8336b8229 评论0 收藏0

发表评论

0条评论

MingjunYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<