Groovy instance.metaclass vs this.metaclass

I have the following 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 conclusion:

 groovy.lang.MetaClassImpl groovy.lang.MetaClassImpl org.codehaus.groovy.runtime.HandleMetaClass org.codehaus.groovy.runtime.HandleMetaClass 

Can someone explain to me what is going on?

Thanks in advance.

+1
metaclass this metaprogramming groovy gradle
source share
1 answer

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}" } } 

enter image description here

Take a look at the groovysh . This may give you a small hint of what is happening.

  • p and q are two different objects, but
  • p.metaClass same as q.metaClass and
  • printAll prints exactly the same thing for both p and q
  • a.metaClass and b.metaClass hold this.class.metaClass , not this.metaClass , you see

There is only one object created from MetaClassImpl , as well as only one from HandleMetaClass , for Person . And no matter how many times you create an instance of Person , they will be assigned to the instance. But when you extend any of these instances, only then will a new HandleMetaClass be created - only for that particular object; and this time, HandleMetaClass will not hold MetaClassImpl , but ExpandoMetaClass .

See screenshot below

enter image description here

Now, to answer your question, this.metaClass is a special case, like this . It does not give you a HandleMetaClass object HandleMetaClass , so you cannot directly extend metaClass of this -; and this makes no sense, because then all other future instances will share this extension.

If you really need this behavior, you can pass this some other variable, i.e. instance = this , as it was in the constructor, and then you can extend this instance - and this extension will be true for this and all other future instances. But then, why not add behavior to the class itself, in the first place. Why expand?

+1
source share

All Articles