groovy @Builder AST中的默认值 [英] Default Values in groovy @Builder AST

查看:148
本文介绍了groovy @Builder AST中的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对groovy很陌生,我只是想在这里学习。我有一个简单的pojo如下,我想在这里有一个建设者模式。现在这个类用@Builder annotaion注释。

  @Builder 
类反转{
字符串颜色='绿色'
字符串代码





$ p在我的主类中,如果创建一个Invert类对象,则变量color始终为null 。

  Invert in = new Invert.builder()。code('0000')。build()

使用代码创建对象为0000,但颜色为空。如果有的话,是否有任何解决方法,或者我在这里丢失了一些东西? 解决方案

首先,让我告诉你这是怎么回事。我将从 Invert 类开始:

  @ groovy.transform .builder.Builder 
class Invert {
String color ='Green'
String code
}

因此这与您的示例中的类相同,唯一的区别是 @Builder 的完全限定名称。但请看看Groovy编译代码时发生了什么(这是Groovy控制台中AST查看器的相关代码)。
$ b

Invert class



  @ groovy.transform.builder.Builder 
public class Invert implements groovy.lang.GroovyObject extends java.lang.Object {

private java.lang.String color
private java.lang.String code
...

public Invert(){
color ='Green'
metaClass = / * BytecodeExpression * /
}

public static Invert $ InvertBuilder builder(){
return new Invert $ InvertBuilder()
}

...
}

没什么可奇怪的,尽管注意到在构造函数中将 color 设置为 green



反转$ InvertBuilder类



  public static class Invert $ InvertBuilder implements groovy.lang.GroovyObject extends java.lang.Obje ct {

private java.lang.String color
private java.lang.String code
...

public Invert $ InvertBuilder color(java .lang.String color){
this .color = color
return this
}

public反转$ InvertBuilder代码(java.lang.String code){
this .code = code
return this
}

public反转build(){
反转_theInvert = new Invert()
_theInvert。 color = color
_theInvert .code = code
return _theInvert
}
...

}
b $ p
$ Invert $ InvertBuilder 类是由 @Builder code> AST。它提供了流畅的API。


问题



你有没有发现问题的根源?构建器包含它自己的 color code 字段。然后,当调用 build()时:
$ b


  1. Invert 被创建。此时,实例的 color 是 green

  2. 构建器应用它自己的 color 和 code 字段添加到 Invert 实例中。此时, color 更改为null,因为这是构建器中的默认值。



解决方案



要使用构建器解决此问题,请使用 ExternalStrategy 来定义您自己的构建器类,您可以根据需要设置颜色。这是一个可行的例子:

$ pre code $ class $ Invalid {
字符串颜色
字符串代码

static InvertBuilder builder(){
new InvertBuilder()
}
}

@ groovy.transform.builder.Builder(builderStrategy = groovy.transform.builder .ExternalStrategy,forClass = Invert)
class InvertBuilder {
InvertBuilder(){
color ='Green'
}
}

反转('0000')。build()

assert invert.color =='Green'
assert invert.code =='0000'



替代方案



Groovy提供了一些替代构建方法可能会感兴趣。

 反转invert1 =新反转(代码:'0000',颜色:'蓝')//使用基于地图的构造函数

Invert invert2 = new Invert()。with {//使用Object.with(Closure)
code ='0000'
color ='Blue '

返回委托
}


I am new to groovy and i am just trying to learn here. I have a simple pojo as below, i am trying to have a builder pattern here. Now the class is annotated with @Builder annotaion.

@Builder
class Invert {
      String color = 'Green'
      String code
}

In my main class if create a object of Invert class, variable color is always null.

Invert in = new Invert.builder().code('0000').build()

Object is created with code as 0000 but color as null. Is it expected, if so is there any workaround for this or i am missing something here ?

解决方案

First, let me show you what's going on. I'll start with the Invert class:

@groovy.transform.builder.Builder
class Invert {
      String color = 'Green'
      String code
}

So that's the same class from your example, with the only difference being a fully-qualified name for @Builder. But check out what happens when Groovy compiles the code (this is the relevant code from the AST viewer in the Groovy console).

Invert class

@groovy.transform.builder.Builder
public class Invert implements groovy.lang.GroovyObject extends java.lang.Object { 

    private java.lang.String color 
    private java.lang.String code 
    ...

    public Invert() {
        color = 'Green'
        metaClass = /*BytecodeExpression*/
    }

    public static Invert$InvertBuilder builder() {
        return new Invert$InvertBuilder()
    }

    ...
}

Nothing surprising, although note that the color is set to green in the constructor.

Invert$InvertBuilder class

public static class Invert$InvertBuilder implements groovy.lang.GroovyObject extends java.lang.Object { 

    private java.lang.String color 
    private java.lang.String code 
    ...

    public Invert$InvertBuilder color(java.lang.String color) {
        this .color = color 
        return this 
    }

    public Invert$InvertBuilder code(java.lang.String code) {
        this .code = code 
        return this 
    }

    public Invert build() {
        Invert _theInvert = new Invert()
        _theInvert .color = color 
        _theInvert .code = code 
        return _theInvert 
    }    
    ...

}

The Invert$InvertBuilder class is created by the @Builder AST. It's what provides the fluent API.

The problem

Did you catch the source of the problem? The builder contains its own color and code fields. Then, when build() is called:

  1. An instance of Invert is created. At this point, the instance's color is green.
  2. The builder applies its own color and code fields to the Invert instance. At this point the color is changed to null because that's the default in the builder.

The solution

To solve this issue with a builder, use the ExternalStrategy to define your own builder class, in which you can set the color as you'd like. Here's a working example:

class Invert {
      String color
      String code

      static InvertBuilder builder() {
          new InvertBuilder()
      }
}

@groovy.transform.builder.Builder(builderStrategy=groovy.transform.builder.ExternalStrategy, forClass=Invert)
class InvertBuilder {
    InvertBuilder() {
        color = 'Green'
    }
}

Invert invert = Invert.builder().code('0000').build()

assert invert.color == 'Green'
assert invert.code == '0000'

Alternatives

Groovy provides some alternative building methods you may be interested in.

Invert invert1 = new Invert(code: '0000', color: 'Blue') // Using the Map-based constructor

Invert invert2 = new Invert().with { // using Object.with(Closure)
    code = '0000'
    color = 'Blue'

    return delegate
}

这篇关于groovy @Builder AST中的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆