lombok无法对$前缀的字段进行代码生成

lombok无法对$前缀的字段进行代码生成

lombok作为一款java的代码辅助开发工具,在业界使用广泛,这里不讨论lombok的使用方法,只是写一下lombok的踩坑记录。
如题所示,lombok对于$前缀的字段是无法进行诸如get,set方法的生成的。估计可能会有同学会有疑问,字段的命名为什么要使用$作为前缀,这个我说一句估计大家都懂:前人挖坑后人填。好了,话不多说,具体的实例如下,Demo类使用lombok的Getter和Setter注解:

@Getter
@Setter
public class Demo {
    private String name;
    private String $type;
}

编译后生成的class文件:

public class Demo {
    private String name;
    private String $type;

    public Demo() {
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

可以看到,$type字段并没有对应的get和set方法,我们再以@AllArgsConstructor和@EqualsAndHashCode注解进行测试:

@AllArgsConstructor
@EqualsAndHashCode
public class Demo {
    private String name;
    private String $type;
}

再次编译后生成的class文件:

public class Demo {
    private String name;
    private String $type;

    public Demo(String name) {
        this.name = name;
    }

    public boolean equals(Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Demo)) {
            return false;
        } else {
            Demo other = (Demo)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$name = this.name;
                Object other$name = other.name;
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(Object other) {
        return other instanceof Demo;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $name = this.name;
        int result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }
}

可以看到equals方法中并没有对$type字段进行比较,而hashCode方法也没有使用$type字段参与计算,其他的诸如@NotNul,@ToString注解结果均一样。可能已经有同学发现在这两个方法里面,lombok生成的临时变量均是通过在字段前+$字符进行统一命名,我们可以推测,如果对$为前缀的字段进行处理,那么会与lombok的内部处理逻辑产生冲突。
对于这种$字段的处理其实就很简单了,那就是回归手动创建需要的方法。但是本人依然很好奇lombok到底是把这种字段过滤掉了,还是处理的时候发生错误了。于是就查看了下lombok源码,发现确实lombok在处理字段的过程中有对字段进行过滤,对于$为前缀的字段,都过滤掉了,不会参与后续的AST处理。
查看@Setter注解的主要处理类lombok.eclipse.handlers.HandleSetter,在主流程handle()方法中调用的generateSetterForType()方法里有这样一段代码:

if (EclipseHandlerUtil.filterField(fieldDecl) && (fieldDecl.modifiers & 16) == 0) {
                        this.generateSetterForField(field, (ASTNode)pos.get(), level);
                    }

这个EclipseHandlerUtil.filterField就是对字段进行过滤的地方,具体过滤逻辑如下:

public static boolean filterField(FieldDeclaration declaration) {
        if (declaration.initialization instanceof AllocationExpression && ((AllocationExpression)declaration.initialization).enumConstant != null) {
            return false;
        } else if (declaration.type == null) {
            return false;
        } else if (declaration.name.length > 0 && declaration.name[0] == '$') {
            return false;
        } else {
            return (declaration.modifiers & 8) == 0;
        }
    }

可以看到对于前缀是$的字段都被过滤了。但是具体为什么要过滤前缀是$的字段,即是什么原因导致lombok必须过滤掉这样的字段,这个在源码中本人没有查到,各位如果有谁知道的话,希望能在评论区留下您的灼见。最后,强烈建议大家在开发中一定要按照已有的规范进行开发,不然就会有千奇百怪的问题发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值