I have encountered below groovy script code in the book . And it generated some strange outputs to me.
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:\t\t${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()
it's output is as below:
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
So I am quite confused:
- why is this.metaClass not equal to instance.metaClass?
- further more, I can not use this.metaClass to inject new methods; groovy tells me this.metaClass have no such property, which I intended to inject.
- What does "org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc[groovy.lang.MetaClassImpl@245b4bdc[class Person]]" mean? I know "245b4bdc" may be the object pointer. But why HandleMetaClass and MetaClassImpl have the same pointer value "245b4bdc"?
Currently, I figured out that @245b4bdc is not the "Object reference", So HandleMetaClass@245b4bdc is not necessarily the same instance as MetaClassImpl@245b4bdc. We can use Object.is() method to judge whether they are the same.(I did that, result is false)