首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Groovy instance.metaclass与this.metaclass

Groovy instance.metaclass与this.metaclass
EN

Stack Overflow用户
提问于 2017-07-30 20:35:14
回答 1查看 524关注 0票数 1

我有一个脚本:

代码语言:javascript
复制
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()

产出如下:

代码语言:javascript
复制
groovy.lang.MetaClassImpl
groovy.lang.MetaClassImpl
org.codehaus.groovy.runtime.HandleMetaClass
org.codehaus.groovy.runtime.HandleMetaClass

有人能向我解释一下发生了什么事吗?

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-31 04:32:33

看看这个class

代码语言:javascript
复制
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创建的对象,也只有一个用于PersonHandleMetaClass对象。不管您实例化Person多少次,它们都将被分配给实例。但是,当您展开其中的任何一个实例时,只有在那时才会创建一个新的HandleMetaClass对象--只针对这个特定的对象;而这次,HandleMetaClass将保持的不是MetaClassImpl,而是ExpandoMetaClass

看下面的截图,

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

如果您真的想要这种行为,那么您可以将this传递给其他变量,即instance = this,就像您在构造函数中所做的那样,然后您可以在该instance之上展开--这种扩展对于this和其他所有未来的实例都是正确的。但是,首先,为什么不把这种行为添加到班级本身呢?为什么要扩张?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45404442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档