【问题标题】:replacing toString using Groovy metaprogramming使用 Groovy 元编程替换 toString
【发布时间】:2011-02-21 07:33:23
【问题描述】:

在下面的 Groovy sn-p 中,我尝试替换 hashCodetoString 方法

String.metaClass.toString = {-> "override" }
String.metaClass.hashCode = {-> 22 }

但是当我测试它时,只有 hashCode 的替换有效

String s = "foo"
println s.hashCode()  // prints 22
println s.toString()  // prints "foo"

toString 是不是某种特殊情况(可能出于安全原因)?

【问题讨论】:

    标签: groovy metaprogramming


    【解决方案1】:

    见第一条评论on this issue。它说的是 String 的 toString 和其他与 String 相关的类:

    (...) 似乎是有意的,它可能是 更快调用的好主意 对于不允许的课程 覆盖 toString()。

    【讨论】:

    • 你怎么知道哪些是“不允许覆盖 toString() 的类”?
    • 我发布了一个新问题,希望可以解决问题...jira.codehaus.org/browse/GROOVY-4210
    • 谢谢蒂姆,所以我想简短的回答是“这是一个错误”?
    【解决方案2】:

    这是know defect。 基本上,Groovy 不会正确覆盖作为接口实现一部分的方法。

    这行得通:

    class T {
           def doIt() { true }
    }
    
    def t = new T()
    
    assert t.doIt()
    t.metaClass.doIt = { -> false }
    assert !t.doIt()
    

    这不是:

    interface I {
           def doIt()
    }
    
    class T implements I {
           def doIt() { true }
    }
    
    def t = new T()
    
    assert t.doIt()
    t.metaClass.doIt = { -> false }
    assert !t.doIt()
    

    因为String 中的toString() 来自CharSequence,所以正确的覆盖方法是:

    CharSequence.metaClass.toString = {-> "silly"}
    println "hello world".toString()
    

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 2011-06-28
      • 2012-05-16
      • 2017-03-19
      • 2010-10-14
      • 1970-01-01
      • 2020-09-27
      相关资源
      最近更新 更多