【问题标题】:Cannot replace static method无法替换静态方法
【发布时间】:2016-07-29 15:47:02
【问题描述】:

我正在尝试使用MetaClass 在运行时替换静态方法。

class MyClass {
    private static String getString() {
        'Hello'
    }

    String testString

    MyClass() {
        testString = getString()
    }
}

MyClass.metaClass.static.getString = { ->
    'Hello world!'
}

def test = new MyClass()
assert test.testString == 'Hello world!'

但是这不起作用。

Caught: Assertion failed: 

assert test.testString == 'Hello world!'
       |    |          |
       |    Hello      false
       MyClass@5876a9af

【问题讨论】:

标签: groovy metaclass


【解决方案1】:

由于bug in Groovy 2.4.3,无法通过元类更改私有方法。我已将方法更改为 public(嗯,默认),并更改了构造函数,以便它显式调用它的类的 getString 方法,现在它似乎在 Groovy web console 中工作

编辑后的完整代码:

class MyClass {
    static String getString() {
        'Hello'
    }
    String testString
    MyClass() {
        testString = MyClass.getString()
    }
}
MyClass.metaClass.static.getString = {'Hello world!'}
def test = new MyClass()
assert test.testString == 'Hello world!'

【讨论】:

  • 为什么testString = getString() 的返回值与testString = MyClass.getString() 不同?你知道为什么会出现这种行为吗?
  • 不,很遗憾。我的猜测是,getString() 直接调用该方法,而MyClass.getString() 通过提供元类扩展的相同机制调用它(它在 Groovy 中不像在 Java 中那样“直接”)。 IIRC 我曾经做过一个测试,我不能使用 Java 类的元类扩展。也就是说,对于我的语言知识来说,这是一个太低级的问题,我不会太依赖这个答案。
  • 事实上我发现这个行为更奇怪。我为此发布了a new question。我高度怀疑这是 Groovy 中的一个错误。
猜你喜欢
  • 2019-06-27
  • 2023-03-09
  • 2022-07-22
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 2020-02-10
相关资源
最近更新 更多