添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
很多开发场景需要用到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<T> extends Serializable { Object apply(T source); * setter方法接口定义 @FunctionalInterface public interface ISetter<T, U> extends Serializable { void accept(T t, U u);

2. 定义getter/setter引用转换属性名的工具类

public class BeanUtils {
     * 缓存类-Lambda的映射关系
    private static Map<Class, SerializedLambda> CLASS_LAMDBA_CACHE = new ConcurrentHashMap<>();
     * 转换方法引用为属性名
     * @param fn
     * @return
    public static <T> String convertToFieldName(IGetter<T> 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 <T,R> String convertToFieldName(ISetter<T,R> 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 - 简单高效的轻代码开发框架

  前面已经为大家讲解了类的使用以及属性的相关知识,在一个类中基本上都会出现属性和字段的,属性在变量和常量的文章中有详细讲解到,这里会重新简单介绍到。 1.1 属性的定义 类中基本上都会存在属性,使用`var`和`val`修饰,`var`声明为可变,即可读可写;`val`声明为不可变,即只能读不能改。类中的属性必须初始化值,否则会报错。 I have a below class and i need to get field name from getter method using java reflection.Is it possible to get field name or property name using getter method?class A {private String name;private St... 一般JavaBean属性以小写字母开头,驼峰命名格式,相应的 getter/setter 方法是 get/set 接上首字母大写的属性名。 例如:属性名为userName,其对应的getter/setter 方法是 getUserName/setUserName。但是,还有一些特殊情况:  1、如果属性名的第二个字母大写,那么该属性名直接用作 getter/setter 方法中 get/set 在我们开发过程中常常有一个需求,就是要知道实体类中Getter方法对应的属性名称(Field Name),例如实体类属性到数据库字段的映射,我们常常是硬编码指定 属性名,这种硬编码有两个缺点。 1、编码效率低:因为要硬编码写属性名,很可能写错,需要非常小心,时间浪费在了不必要的检查上。 2、容易让开发人员踩坑:例如有一天发现实体类中Field Name定义的不够明确,希望换一个Field Name... public class GetPropNameTest { public static void main(String[] args) { System.out.println(Getter.propName(new Father()::getName));// name interface Getter extends Serializable { String GETTER_PREFIX = "get"; Object get(); 最近在开发的过程中,发现了大量的lambda表达式,看着帅气而有简洁的代码,我也有点心动了,于是学习了其用法,lambda概念以及特点我在这里就不多作概述了,不懂的朋友可以自行去了解下,在这里我直接上代码,不喜无喷!! 一:添加一些基类和原始数据 public class Deptment { private String name; private String ad... 内省是 Java 语言对 Bean 类属性、事件的一种处理方法(也就是说给定一个javabean对象,我们就可以得到/调用它的所有的get/set方法)。例如类 A 中有属性 name, 那我们可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java 中提供了一套 API 用来访问某个属性的 ge 编写Lambda表达式作为方法引用 您看到,lambda表达式实际上是方法实现:函数式接口的唯一抽象方法。有时人们称这些lambda表达式为“匿名方法”,因为它只是:一个没有名称的方法,你可以在应用程序中传递,存储在一个字段或变量中,作为参数传递给一个方法或构造函数,并从一个方法返回。 有时你会编写lambda表达式,只是调用在其他地方定义的特定方法。事实上,当你写下面的代码时,你已经做到了: Consumer<String> printer = s -> System.out.prin 知乎里的一个答案:https://www.zhihu.com/question/21401198 的确可以暴露,如果1. 所有内外代码都是你自己写;2. 这个模块再也不改了;3. 不会继承它,或者继承但不改变语义。 David John Wheeler有一句名言: “All problems in computer science can be solved by another level lombok是一个帮助简化代码的工具,通过注解的形式例如@Setter @Getter,可以替代代码中的gettersetter方法,虽然eclipse自带的settergetter代码生成也不需要我们手动的去敲写,但是使用@Setter @Getter这样的注解,能够使我们的代码看上去更加的简洁、优雅。 lombok下有许多常用注解,这里主要讲@Getter和@Setter的一个注意点。 public static void main(String[] args){ Map<String,String> map= new HashMap<>(); map.forEach((k,v)->{ // 打印键 System.out.println(k);