是否可以直接引用用 @Builder 声明的生成器类?



以下Groovy脚本编译失败:

import groovy.transform.builder.Builder
@Builder
class Foo {
String bar
}
Foo.FooBuilder aBuilder = Foo.builder()

编译错误为:

错误:(8, 16( Groovyc: 无法解析类 Foo.FooBuilder

这是预期行为吗?任何已知的解决方法?

时髦版本:2.5.2(我也检查了 2.4.12 和 2.4.15(

这是正确的。该行

Foo.FooBuilder aBuilder = Foo.builder()

将在尝试解析所有预期类型(在左侧声明的类型(的阶段Phases.SEMANTIC_ANALYSIS失败。此阶段在生成类FooBuilderPhases.CLASS_GENERATION之前执行 - 这就是为什么编译器抱怨不存在的FooBuilder类(它根本没有生成(。

解决方法

此问题有一个简单的解决方法 - 使用def和类型推断来传递语义分析阶段,并让编译器生成FooBuilder类。

import groovy.transform.builder.Builder
@Builder
class Foo {
String bar
}
def aBuilder = Foo.builder()
println aBuilder.dump()

作为旁注 - 有一种方法可以使Foo.FooBuilder aBuilder = Foo.builder() 通过静态分析阶段。如果跳过声明Foo.FooBuilder类型

import groovy.transform.builder.Builder
@Builder
class Foo {
String bar
}
//Foo.FooBuilder aBuilder = Foo.builder()

并使用编译器编译groovyc此类,它将生成Foo.class以及Foo$FooBuilder.class。然后,如果您取消注释引发编译异常的行并运行脚本,它将编译并运行,没有任何问题。诀窍在于Groovy编译器编译Foo.FooBuilder类(并将其保存为Foo$FooBuilder.class文件(,因此当您运行脚本并且静态分析尝试解析它时,它在当前类路径中可用。在这种情况下,语义分析阶段不会报告您之前遇到的错误。但是,我只是作为一个有趣的事实而不是解决方法提及它,因为它很难使用。在这种情况下,改用def关键字并依赖类型推断效果最佳。

最新更新