Groovy:this.metaClass与instance.metaClass相对应
我在书中遇到了下面的groovy脚本代码.它给我带来了一些奇怪的输出.
class Person{ def work(){ println "work()" } def sports=['basketball','football','voleyball'] def methodMissing(String name,args){ if(name in sports){ println "injected ${name} into Person class" Person instance=this println "this.metaClass:tt${this.metaClass}" println "instance.metaClass:t${instance.metaClass}" assert this.metaClass==instance.metaClass }else{ println "no such method:${name}() in Person class" } } } def jack=new Person() jack.football() 它的输出如下: injected football into Person class this.metaClass: groovy.lang.MetaClassImpl@245b4bdc[class Person] instance.metaClass: org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc[groovy.lang.MetaClassImpl@245b4bdc[class Person]] Caught: Assertion failed: //I did not paste the detailed assertion here for simplicity 所以我很困惑: >为什么this.metaClass不等于instance.metaClass? 目前,我发现@ 245b4bdc不是“对象引用”,因此HandleMetaClass @ 245b4bdc不一定与MetaClassImpl @ 245b4bdc相同.我们可以使用Object.is()方法来判断它们是否相同.(我这样做,结果是假的) 解决方法
>为什么this.metaClass!= instance.metaClass?
它涉及沟槽进入田地. >从“outside”访问实例字段时,groovy实际上调用函数getFieldName().在我的例子中,当我使用“实例”时,我在外面;因此instance.metaClass将调用instance.getMetaClass(). >为什么this.metaClass.say = { – > println“say”}会抛出MissingPropertyException? > this.metaClass的类型是MetaClassImpl 代码示例(问题1): class Person{ def work(){ println "work()" } def sports=['basketball',args){ if(name in sports){ Person instance=this println "this.metaClass:nt${this.metaClass}" println "instance.metaClass:nt${instance.metaClass}" //output: false println "this.metaClass.is(instance.metaClass):nt${this.metaClass.is(instance.metaClass)}" //output: true println "this.getMetaClass().is(instance.getMetaClass()):nt${this.getMetaClass().is(instance.getMetaClass())}" }else{ println "no such method:${name}() in Person class" } } } def jack=new Person() jack.football() jack.football() 代码示例(问题2): class Cat{} def a=new groovy.lang.MetaClassImpl(Cat) try{ a.say={->println "say"} }catch(MissingPropertyException e){ println "[Fail]ntcan not inject method say() into MetaClassImpl class.n" } def b=new org.codehaus.groovy.runtime.HandleMetaClass(a) println b b.say={->println "[say]"} println "[OK]ntcan inject method say() into HandleMetaClass classn" def method=b.getMetaMethod("say") method.invoke(this) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |