加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Groovy:this.metaClass与instance.metaClass相对应

发布时间:2020-12-14 16:36:02 所属栏目:大数据 来源:网络整理
导读:我在书中遇到了下面的groovy脚本代码.它给我带来了一些奇怪的输出. class Person{ def work(){ println "work()" } def sports=['basketball','football','voleyball'] def methodMissing(String name,args){ if(name in sports){ println "injected ${name}
我在书中遇到了下面的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?
>更进一步,我不能使用this.metaClass来注入新方法; groovy告诉我this.metaClass没有这样的属性,我打算注入.
>“org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc [groovy.lang.MetaClassImpl@245b4bdc [class Person]]”是什么意思?我知道“245b4bdc”可能是对象指针.但是为什么HandleMetaClass和MetaClassImpl具有相同的指针值“245b4bdc”?

目前,我发现@ 245b4bdc不是“对象引用”,因此HandleMetaClass @ 245b4bdc不一定与MetaClassImpl @ 245b4bdc相同.我们可以使用Object.is()方法来判断它们是否相同.(我这样做,结果是假的)

解决方法

>为什么this.metaClass!= instance.metaClass?

它涉及沟槽进入田地.

>从“outside”访问实例字段时,groovy实际上调用函数getFieldName().在我的例子中,当我使用“实例”时,我在外面;因此instance.metaClass将调用instance.getMetaClass().
>从“inside”访问实例字段时,groovy只是直接访问该字段,不调用getFieldName().在我们的例子中,当我使用“this”时,我处于“内部”;所以“this.metaClass”将直接访问“metaClass”.
>最后,getMetaClass()返回一个HandleMetaClass对象,而内部metaClass是一个MetaClassImpl对象.所以this.metaClass!= instance.metaClass.

>为什么this.metaClass.say = { – > println“say”}会抛出MissingPropertyException?

> this.metaClass的类型是MetaClassImpl
> MetaClassImpl是一个低级类,它支持高级类(例如HandleMetaClass)进行注入.它不适合开发人员直接使用,因此它不支持注入方式:xxxx.say = { – > println“say”}.

代码示例(问题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)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读