Lombok.val如何实际工作?

Mic*_*ael 12 java annotations lombok

Lombok.val允许你

使用val作为局部变量声明的类型,而不是实际写入类型.执行此操作时,将从初始化表达式推断出类型.局部变量也将成为最终变量.

而不是

final ArrayList<String> example = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

你可以写

val example = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

我试图对这实际上是如何工作进行一些研究,但似乎没有大量的信息.看一下github页面,我可以看到它val是一个注释类型.然后使用注释类型,而不是实际注释.

我甚至不知道你甚至可以用这种方式使用注释类型,但在测试它时,下面的代码确实有效.但是,我仍然不确定为什么你会想要以这种方式使用该类型.

public class Main
{
    public @interface Foo { }

    public static void main(String... args)
    {       
        Foo bar;
        System.out.println("End");
    }
}
Run Code Online (Sandbox Code Playgroud)

如果Lombok不是注释,而是注释类型,它们如何处理这些用法?对于我(显然不正确)的理解,语法看起来应该更像:

@Val foo = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)

(我知道注释的约束意味着上面的语法不是有效的)

Roe*_*ker 29

为了使Lombok工作,源代码需要解析而不会出错.正如您已经提到的那样,这就是为什么@val foo = new ArrayList<String>();不起作用的原因.

尽管Lombok使用注释和注释处理器,但注释处理器仅用作编译器参与的手段.

Lombok没有注册处理器@val.相反,它处理所有java文件,访问整个AST并替换val局部变量的初始化表达式的类型.

披露:我是Lombok开发人员.

  • 对于Eclipse和ecj,请参阅https://github.com/rzwitserloot/lombok/blob/master/src/eclipseAgent/lombok/eclipse/agent/PatchVal.java和https://github.com/rzwitserloot/lombok/blob/ master/src/eclipseAgent/lombok/eclipse/agent/PatchValEclipse.java,对于javac,请参阅https://github.com/rzwitserloot/lombok/blob/master/src/core/lombok/javac/handlers/HandleVal.java (3认同)