i have the flowing script:
task myTask {}
class Person {
Person() {
Person instance = this
println this.metaClass.class.name
println this.getMetaClass().class.name
println instance.metaClass.class.name
println instance.getMetaClass().class.name
}
}
Person person = new Person()
And the output is :
groovy.lang.MetaClassImpl
groovy.lang.MetaClassImpl
org.codehaus.groovy.runtime.HandleMetaClass
org.codehaus.groovy.runtime.HandleMetaClass
can anyone explain to me what is going on ?
thanks in advance.
Take a look at this class
,
class Person {
def a, b
Person() {
a = this
b = this
println "this $this"
println "a $a"
println "b $b"
}
def printAll() {
println "this.metaClass ${this.metaClass}"
println "this.class.metaClass ${this.class.metaClass}"
println "a.metaClass ${a.metaClass}"
println "b.metaClass ${b.metaClass}"
}
}
Take a look at the screenshot of the groovysh
. It might give you a little hint about what's going on.
p
and q
are two different objects, but
p.metaClass
is the same as q.metaClass
, and
printAll
prints exactly the same thing for both, p
and q
a.metaClass
and b.metaClass
are holding this.class.metaClass
, not this.metaClass
, you see
There is only one object created of MetaClassImpl
, and also only one of HandleMetaClass
, for Person
. And no matter how many times you instantiate Person
, they will be assigned to the instance. But, when you expand any of that instance, only then a new HandleMetaClass
object will be created -- just for that particular object; and this time HandleMetaClass
will be holding not MetaClassImpl
, but ExpandoMetaClass
instead.
See the screenshot below,
Now, to answer your question, this.metaClass
is a special case, like this
itself. It doesn't give you the handle, HandleMetaClass
object, so you can't expand over metaClass
of this
-- directly; and there is no sense in that either, because then all other future instances will share that expansion.
If you really want that behaviour then you can pass this
to some other variable, i.e. instance = this
, as you did in the constructor, and then you can expand over that instance
-- and that expansion would be true for this
and all other future instances. But then, why not add the behaviour to class itself, in the first place. Why expand?