Groovy metaClass терпит неудачу при переопределении метода, вызванного в конструкторе?


Я только что попытался написать этот простой код для тестирования методов переопределения с помощью metaClass.

Код здесь:

class Hello {

    public Hello()  
    {
        Foo()
    }

    public void Foo()
    {
        println "old"   
    }       

}

У него есть метод Foo (), который просто выводит "old", и он был вызван конструктором.

Вот тестовый код:

class HelloTest {

    @Test
    public void test() {

        boolean methodFooWasCalled = false

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

        Hello hello = new Hello()

        assertTrue methodFooWasCalled == true

    }
}

Я ожидал, что вывод должен быть "новым", так как Foo() был переопределен. Но он все равно напечатал "старый". Кто-нибудь знает, почему это не удается? Спасибо

1 9

1 ответ:

Следующие работы:

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

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

new Hello()

И то же самое делает следующее:

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

  void Foo() { println "old" }
}

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

new Hello()

Это интересно; вызов bar() внутри Foo() работает, в то время как внутри конструктора нет:

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()

Похоже, Groovy не проверяет методы метакласса сначала, когда на конструкторах. Я думаю, что это ошибка, и я не смог найти никакой ошибки, связанной с этим. А как насчет заполнения Джиры ?