【问题标题】:Groovy instance.metaclass vs this.metaclassGroovy instance.metaclass 与 this.metaclass
【发布时间】:2018-01-06 08:24:22
【问题描述】:

我有以下脚本:

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()

输出是:

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

谁能给我解释一下这是怎么回事?

提前致谢。

【问题讨论】:

  • 您是否难以理解this.instance.metaClassgetMetaClass 之间的区别?
  • 我检查了那个帖子,这个帖子是矛盾的!为什么 instance.metaClass 也不同于 this.getMetaClass() ?
  • 这篇文章完美地解释了这一点:stackoverflow.com/questions/5340189/… instance 基本上是与this 不同的元类。这是 org.codehaus 的版本。
  • 我会检查的,谢谢。

标签: gradle groovy this metaprogramming metaclass


【解决方案1】:

看看这个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}"
    }
}

看看groovysh的截图。它可能会给您一些关于正在发生的事情的提示。

  1. pq 是两个不同的对象,但是
  2. p.metaClassq.metaClass 相同,并且
  3. printAllpq 打印完全相同的内容
  4. a.metaClassb.metaClass 持有 this.class.metaClass,而不是 this.metaClass,你看

MetaClassImpl 只创建了一个对象,HandleMetaClass 也只创建了一个对象,用于Person。而且无论您实例化Person 多少次,它们都会被分配给实例。但是,当您扩展该实例中的任何一个时,才会创建一个新的 HandleMetaClass 对象——仅针对该特定对象;而这次HandleMetaClass 将不是MetaClassImpl,而是ExpandoMetaClass

请看下面的截图,

现在,回答您的问题,this.metaClass 是一个特例,就像 this 本身一样。它没有给你句柄 HandleMetaClass 对象,所以你不能直接扩展 metaClassthis -- ;这也没有任何意义,因为所有其他未来实例都将共享该扩展。

如果您真的想要这种行为,那么您可以将this 传递给其他变量,即instance = this,就像您在构造函数中所做的那样,然后您可以扩展该instance——并且该扩展将是this 和所有其他未来实例为 true。但是,为什么不首先将行为添加到类本身。为什么要扩展?

【讨论】:

  • 非常感谢,但我不明白这与人的构造函数代码块中的实例有何不同。你能澄清一下吗?
  • 非常感谢
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多