2

我试图通过替换该类中用于设置属性但未使用预期值设置属性的方法来更改 groovy 类的构造函数的行为。

class TestClass {

    def noParam
    def withParam

    TestClass() {
        noParam = noParam()
        withParam = withParam('second test')
    }

    def noParam() {
        return 'first test'
    }

    def withParam(param) {
        return param
    }

}

TestClass.metaClass.withParam =  { param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }

def test = new TestClass()

assert test.withParam('dummy') == 'pass' //passes
assert test.withParam == 'pass' // fails
assert test.noParam() == 'pass' // passes
assert test.noParam == 'pass' // fails
4

1 回答 1

1

noParam当 Groovy 执行andwithParam方法时,它不会在 TestClass 构造函数中使用您的元类覆盖。事实上,如果你在withParam方法中键入参数,第二个断言也会失败。

class TestClass {

    def noParam
    def withParam

    TestClass() {
        noParam = noParam()
        withParam = withParam('second test')
        println "in the constructor: noParam = $noParam, withParam = $withParam"
    }

    def noParam() {
        return 'first test'
    }

    def withParam(String param) {
        return param
    }
}

TestClass.metaClass.withParam = { String param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }

def test = new TestClass()

assert test.withParam('dummy') == 'pass'
assert test.withParam  == 'pass' // this fails now too!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // this fails

这是输出:in the constructor: noParam = first test, withParam = second test

test.withParam并且test.noParam实际上是在调用test.getWithParam()test.getNoParam()- 他们正在返回构造函数中设置的属性值。

test.withParam('dummy')test.noParam()调用您的元类方法并返回“通过”。

至于为什么groovy 不在你的构造函数中使用元类方法,我不确定......我在元类文档中找不到任何东西......

也许您可以改用静态方法?

class TestClass {

    def noParam
    def withParam

    TestClass() {
        noParam = TestClass.noParam()
        withParam = TestClass.withParam('second test')
        println "in the constructor: noParam = $noParam, withParam = $withParam"
    }

    static def noParam() {
        return 'first test'
    }

    static def withParam(String param) {
        return param
    }
}

TestClass.metaClass.'static'.withParam = { String param -> 'pass' }
TestClass.metaClass.'static'.noParam = {-> 'pass' }

def test = new TestClass()

assert test.withParam('dummy') == 'pass'
assert test.withParam  == 'pass' // passes!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // passes!

这是输出:in the constructor: noParam = pass, withParam = pass

于 2013-06-14T21:53:47.293 回答