Mic*_*l M 5 groovy metaprogramming
因此,向接口元类添加方法会将其添加到接口实现 \xe2\x80\x93 的每个实例中,但仅一次。将方法添加到每个实现类中每次都可以进行更改。
\n\n在重新分配方法之间清理元类似乎没有改变任何东西。
\n\n这是一个可运行的示例:
\n\ninterface X {}\nclass A implements X {}\nclass B implements X {}\n\nX.metaClass.test = { println "v1" }\nnew A().test()\nnew B().test()\n\nX.metaClass.test = { println "v2" }\nnew A().test()\nnew B().test()\n\nA.metaClass.test = { println "v3" }\nB.metaClass.test = { println "v3" }\n\nnew A().test()\nnew B().test()\n\nA.metaClass.test = { println "v4" }\nB.metaClass.test = { println "v4" }\n\nnew A().test()\nnew B().test()\nRun Code Online (Sandbox Code Playgroud)\n\n结果是:
\n\nv1\nv1\nv1\nv1\nv3\nv3\nv4\nv4\nRun Code Online (Sandbox Code Playgroud)\n\n这是有意的行为吗?如果是这样,那为什么呢?或者这是一个错误?
\n哇,我认为这实际上可能是一个长期存在的未解决的错误(GROOVY-3493)。看起来问题是,一旦在接口中声明了方法,就无法通过元类覆盖它。此限制不适用于课程。
\n\n所以我的猜测是,第一次通过元类声明该方法时,它已正确初始化,因为它以前不存在。但是对接口元类方法的任何后续更新都不起作用,因为它已经存在。类元类更改有效,因为此错误不适用于它们。
\n\n票证中列出的解决方法似乎与您找到的解决方法类似;即,更新接口和类上的元类:
\n\n\xe2\x80\x8binterface X {}\nclass A implements X {} \nclass B implements X {} \n\nX.metaClass.test = { println "v1" } \n\nnew A().test() \nnew B().test() \n\nX.metaClass.test = { println "v2" } \nA.metaClass.test = { println "v2" }\n\nnew A().test() // Will print "v2"\nnew B().test()\xe2\x80\x8b // Will print "v1" still\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
233 次 |
| 最近记录: |