Это правильно.Строка
Foo.FooBuilder aBuilder = Foo.builder()
потерпит неудачу во время фазы Phases.SEMANTIC_ANALYSIS
, которая пытается разрешить все ожидаемые типы (те, которые объявлены слева).Эта фаза выполняется до Phases.CLASS_GENERATION
, который генерирует класс FooBuilder
- поэтому компилятор жалуется на несуществующий класс 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
type
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
и полагаться на вывод типа.