2

给定一个具有属性和构造函数的对象,我希望将构造函数参数复制到属性中,然后在构造函数中做一些额外的工作。

import groovy.transform.TupleConstructor

@TupleConstructor
class Thing{
    def one
    def two

    public Thing(one, two){
       doSomething()
    }

    def doSomething(){
        println "doing something with one : $one and two: $two"
    }
}


println new Thing(1, 2).dump()

如果我在构造函数中什么都不做,这将成功地将 args 复制到属性中,但是如果我在构造函数中调用“doSomething()”,则不会复制属性。

我正在寻找将 args 复制到属性的“The Groovy”方式。

4

2 回答 2

6

正如 tim_yates提到的,如果您定义了另一个构造函数,则 TupleConstructor AST 转换不会做任何事情(您可以责怪这行代码 =P)。如果您需要在对象的构造中运行一些其他代码,您可以将其添加到静态工厂方法中并直接使用它而不是元组构造函数:

import groovy.transform.TupleConstructor

@TupleConstructor
class Thing {
    def one
    def two

    def doSomething(){
        println "doing something with one : $one and two: $two"
    }

    static create(...args) {
        def thing = new Thing(*args)
        thing.doSomething()
        thing
    }
}


println Thing.create(1, 2).dump()

请注意,我使用可变参数静态方法来接收任意数量的参数,然后使用这些参数调用元组构造函数(为此使用了“spread”(*)运算符)。

不幸的是,TupleConstructor AST 转换似乎没有将元组构造函数添加为私有的选项,这在这种情况下很有用。

于 2012-05-04T16:24:03.323 回答
4

如果您使用TupleConstructor,如果您定义了自己的构造函数,它将不会运行。

并且由于您已经定义了一个重复的构造函数,TupleConstructor它将在字节码中生成,即使这样做@TupleConstructor( force=true )也无济于事,因为您只会得到一个java.lang.ClassFormatError: Duplicate method name&signature in class file Thing

目前我能想到的最好的方法是:

class Thing{
    def one
    def two

    public Thing( Map params ){
       this.class.declaredFields.grep { !it.synthetic }.name.each { name ->
         this[ name ] = params[ name ]
       }
       doSomething()
    }

    def doSomething(){
        println "doing something with one : $one and two: $two"
    }
}


println new Thing(one:1, two:2).dump()

尽管我可能缺少更好的方法

于 2012-05-04T15:10:20.457 回答