什么语法`@__()`在Lombok中意味着什么?

And*_*lko 15 java lombok

我一直在和Lombok一起工作并积极使用2个月.使用Java我更熟悉一点.但是,我第一次面对语言中的以下语法结构:

@RequiredArgsController(onController = @__(@Autowired))
                                       ^^^
Run Code Online (Sandbox Code Playgroud)

这是什么意思,它是如何编译的?

Sto*_*ica 15

这是一个实验性的Lombok语法,创建用于在引用多个注释时支持一个间接层,而不是使用Class<?>[].

语法有点奇怪; 要使用这3个onX功能中的任何一个,必须将要应用的注释包装到构造函数/方法/参数中@__(@AnnotationGoesHere).要应用多个注释,请使用@__({@Annotation1, @Annotation2}).注释本身显然也有参数.

https://projectlombok.org/features/experimental/onX.html

Lombok开发人员Roel Spilker的解释:

原因是javac已经在解析阶段解析了注释,并且如果它可以确定注释是无效的则会给出错误.通过使用不存在的注释,@__它不能确定它是伪造的(它可能由注释处理器创建)并且不会立即给出错误.这使得Lombok有时间完成工作并@__从代码中删除.

  • 原因是javac已经在解析阶段解析了注释,并且如果它可以确定注释是无效的则会给出错误.通过使用不存在的注释"@__",它无法确定它是否为伪造(它可能由注释处理器创建)并且不会立即给出错误.这使得Lombok有时间完成工作并从代码中删除`@__`. (4认同)

zap*_*apl 8

这意味着生成的构造函数(不是控制器)也会@Autowired添加注释,以便spring可以发挥其魔力.使用lombok,您可以编写代码

@RequiredArgsConstructor(onConstructor=@__(@Autowired(required=true)))
public class FooController {
    private final FooService service;
    interface FooService {}
}
Run Code Online (Sandbox Code Playgroud)

和lombok将在编译期间将其转换为

public class FooController {
    private final FooService service;
    @Autowired(required=true)
    public FooController(FooService service) {
        this.service = service;
    }
}
Run Code Online (Sandbox Code Playgroud)

@__ 用于克服注释的类型限制,因为

@interface MultipleAnnotations {
    Annotation[] value();
}
Run Code Online (Sandbox Code Playgroud)

不起作用,因为所有注释的超类型本身不是注释和

@interface MultipleAnnotations {
    Class<? extends Annotation>[] value();
}
Run Code Online (Sandbox Code Playgroud)

不允许注释中的参数: @MultipleAnnotations(SomeAnnotation.class)

  • lombok 团队已[提交提案](https://projectlombok.org/anyannotation/) 将 Annotation[] 的可能性添加到注释中,但已被拒绝。也许有一天我们可以复活它...... (2认同)

sin*_*ohn 8

对于对这种奇怪的语法感到困惑的 JDK8 用户,这里提到了一种更简洁的方法-On javac8 and up, you add an underscore after onMethod, onParam, or onConstructor.

所以它会从@RequiredArgsController(onController = @__(@Autowired))变为@RequiredArgsController(onController_ = @Autowired)

  • 我认为它是 @RequiredArgsConstructor(onConstructor_ = @Autowired) 而不是 @RequiredArgsController (4认同)