使用命名参数调用父构造函数

时间:2013-11-24 11:45:33

标签: groovy

我正在尝试在Java应用程序中嵌入POGO。我想使用POGO用一些虚拟数据来实例化POJO以进行测试。我认为POGO可以扩展POJO并使用命名参数调用POJO的构造函数,如下例所示:

Java类:

public class Pojo {
  private String name;
  ...
}

Groovy类:

class Pogo extends Pojo {
  Pogo() {
    super(name: 'test name')
  }
}

尝试通过

从JUnit测试中实例化Pogo
@Test
public void shouldInitPojoWithTestData() {
    Pojo p = new Pogo();

    assertNotNull(p);
    assertEquals("test name", p.getName());
}

失败
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: Pojo(java.util.LinkedHashMap)

但是,在Groovy脚本中使用命名参数实例化POJO可以正常工作:

def p = new Pojo(name: 'test name')
assert p.name == 'test name' // OK

为什么我不能使用命名参数调用父构造函数?

THX

1 个答案:

答案 0 :(得分:3)

命名的构造函数参数是一种语法糖。它将被转换为一个链,从默认的无参数构造函数开始,然后是mutator调用。

例如,当您致电

def p = new Pojo(name: 'test name')

它将被翻译为:

def p = new Pojo()
p.setName('test_name')

super调用是对父类构造函数的直接调用。将命名参数合并到Map实例,然后,我们尝试使用单个map参数调用super

编译器告诉你,没有这样的构造函数。

你可以声明它并从给定的地图中手动提取字段值,但在Java中它将是不可靠的(手动,如this.name = map.get(“name”))或复杂(通过反思)。

您可以在POGO中使用工厂方法来创建pojo。喜欢这个

class POGO {
   static Pojo createPOJO() {
       new Pojo(name: 'test_name')
   }
}