Groovy 在不丢失默认映射构造函数的情况下添加自定义构造函数
默认情况下,每个Groovy类都有一个映射构造函数,例如Groovy 在不丢失默认映射构造函数的情况下添加自定义构造函数,groovy,constructor,Groovy,Constructor,默认情况下,每个Groovy类都有一个映射构造函数,例如 class Foo { def a def b } // this works new Foo(a: '1', b: '2') 但是,似乎只要添加自己的构造函数,这个默认构造函数就不可用 class Foo { Foo(Integer x) { println 'my constructor was called' } def a def b } // this works new Foo(1
class Foo {
def a
def b
}
// this works
new Foo(a: '1', b: '2')
但是,似乎只要添加自己的构造函数,这个默认构造函数就不可用
class Foo {
Foo(Integer x) {
println 'my constructor was called'
}
def a
def b
}
// this works
new Foo(1)
// now this doesn't work, I get the error: groovy.lang.GroovyRuntimeException:
// failed to invoke constructor
new Foo(a: '1', b: '2')
是否可以在不丢失默认映射构造函数的情况下添加自己的构造函数?我尝试使用@TupleConstructor
注释该类,但没有任何区别。我意识到我可以自己添加地图构造器,例如
public Foo(Map map) {
map?.each { k, v -> this[k] = v }
}
尽管上面的构造函数与默认的map构造函数不同,因为map中的键在类中没有相应的属性将导致异常。如果您使用的是Groovy 2.5或更高版本,则可以应用
@MapConstructor
如果您使用的是较旧版本的Groovy,
@inheritarconstructor
可以用作@MapConstructor
的替代品,但正如Arie所指出的,如果您的类扩展了一些基类,请避免使用这种方法;如果基类缺少no-arg构造函数,这将不起作用。编译后,Groovy的映射构造函数将被转换为(javabean样式的)。使用空构造函数可以解决此问题:
class Foo {
Foo(Integer x) {
println 'my constructor was called'
}
Foo() {}
def a
def b
}
new Foo(1)
foo = new Foo(a: '1', b: '2')
assert foo.a == "1"
添加一个无参数选择器并调用
super
,例如
class Foo {
Foo(Integer x) {
println 'my constructor was called'
}
Foo() { super() } // Or just Foo() {}
def a
def b
}
f = new Foo(a: '1', b: '2')
println f.a
=> 1
这很可能是一个更干净的选项。这是因为
Foo
从基对象
类继承了默认的无参数构造函数。如果基类没有arg构造函数,它将崩溃;如果基类有多个重载构造函数,它将污染构造函数空间@威尔的答案是正确的。
class Foo {
Foo(Integer x) {
println 'my constructor was called'
}
Foo() { super() } // Or just Foo() {}
def a
def b
}
f = new Foo(a: '1', b: '2')
println f.a
=> 1