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

Groovy 使用命名参数调用父构造函数,groovy,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

我正在尝试在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
为什么我不能用命名参数调用父构造函数


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

例如,当你打电话时

def p = new Pojo(name: 'test name')
它将被翻译成:

def p = new Pojo()
p.setName('test_name')
super
调用是对父类构造函数的直接调用。命名参数合并到一个映射实例,然后,我们尝试使用单个映射参数调用
super

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

您可以声明它并从给定的映射中手动提取字段值,但在Java中,它将是不可靠的(手动的,比如这个.name=map.get(“name”))或复杂的(通过反射)

您可以在POGO中使用factory方法来创建pojo。像这样

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