我有一个脚本:
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有人能向我解释一下发生了什么事吗?
提前谢谢。
发布于 2017-07-31 04:32:33
看看这个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的截图。这可能会给你一些关于发生了什么的提示。
p和q是两个不同的对象,但是p.metaClass与q.metaClass相同,并且printAll为p和q打印完全相同的内容a.metaClass和b.metaClass持有this.class.metaClass,而不是this.metaClass,你看只有一个由MetaClassImpl创建的对象,也只有一个用于Person的HandleMetaClass对象。不管您实例化Person多少次,它们都将被分配给实例。但是,当您展开其中的任何一个实例时,只有在那时才会创建一个新的HandleMetaClass对象--只针对这个特定的对象;而这次,HandleMetaClass将保持的不是MetaClassImpl,而是ExpandoMetaClass。
看下面的截图,

现在,为了回答您的问题,this.metaClass是一个特例,就像this本身一样。它没有给您句柄,HandleMetaClass对象,所以您不能在metaClass of this上进行扩展--直接扩展;这也没有任何意义,因为以后所有其他实例都将共享该扩展。
如果您真的想要这种行为,那么您可以将this传递给其他变量,即instance = this,就像您在构造函数中所做的那样,然后您可以在该instance之上展开--这种扩展对于this和其他所有未来的实例都是正确的。但是,首先,为什么不把这种行为添加到班级本身呢?为什么要扩张?
https://stackoverflow.com/questions/45404442
复制相似问题