Groovy metaClass fails when overriding method called in constructor?

让人想犯罪 __ 提交于 2019-12-18 07:40:32

问题


I just tried to write this simple code to test overriding methods using metaClass.

The code is here:

class Hello {

    public Hello()  
    {
        Foo()
    }

    public void Foo()
    {
        println "old"   
    }       

}

It has a Foo() method which simply prints "old" and it was called by the constructor.

Here's the test code:

class HelloTest {

    @Test
    public void test() {

        boolean methodFooWasCalled = false

        Hello.metaClass.Foo = {-> println "new"
            methodFooWasCalled = true
        }

        Hello hello = new Hello()

        assertTrue methodFooWasCalled == true

    }
}

I was expecting that the output should be "new" since Foo() has been overriden. But it still printed "old". Does anyone know why it fails? Thanks


回答1:


The following works:

class Hello {
  Hello() {
    Foo()
  }
}

Hello.metaClass.Foo = {-> 
  println "new"
}

new Hello()

And so does the following:

class Hello {
  Hello() {
    invokeMethod('Foo', [] as Object[])
  }

  void Foo() { println "old" }
}

Hello.metaClass.Foo = {-> 
  println "new"
}

new Hello()

This one is interesting; the bar() call inside Foo() works, whilst the ones inside the constructor doesn't:

class Hello {
  Hello() {
    Foo()
    bar()
  }

  void Foo() { println "old foo"; bar() }
  void bar() { println "old bar" }
}

Hello.metaClass {
  Foo = {-> println "new foo" }
  bar = { println "new bar" }
}

new Hello()

It appears Groovy doesn't check metaclass' methods FIRST when on constructors. I think it is a bug, and i couldn't find any bug related to this. What about filling a JIRA?



来源:https://stackoverflow.com/questions/27489785/groovy-metaclass-fails-when-overriding-method-called-in-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!