Groovy instance.metaclass 对比 this.metaclass
Groovy instance.metaclass vs this.metaclass
我有以下脚本:
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
谁能给我解释一下这是怎么回事?
提前致谢。
看看这个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
只创建了一个对象,HandleMetaClass
也只有一个对象,Person
。而且无论你实例化多少次Person
,它们都会被赋值给实例。但是,当您展开该实例中的任何一个时,只会为该特定对象创建一个新的 HandleMetaClass
对象;这次 HandleMetaClass
持有的不是 MetaClassImpl
,而是 ExpandoMetaClass
。
看下面的截图,
现在,回答你的问题,this.metaClass
是一个特例,就像 this
本身一样。它不会为您提供 HandleMetaClass
对象的句柄,因此您不能直接扩展 this
的 metaClass
;并且这也没有任何意义,因为所有其他未来实例都将共享该扩展。
如果你真的想要那种行为,那么你可以将 this
传递给其他一些变量,即 instance = this
,就像你在构造函数中所做的那样,然后你可以扩展 instance
-- 并且该扩展对于 this
和所有其他未来实例都是正确的。但是,为什么不首先将行为添加到 class 本身。为什么要扩展?
我有以下脚本:
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
谁能给我解释一下这是怎么回事?
提前致谢。
看看这个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
只创建了一个对象,HandleMetaClass
也只有一个对象,Person
。而且无论你实例化多少次Person
,它们都会被赋值给实例。但是,当您展开该实例中的任何一个时,只会为该特定对象创建一个新的 HandleMetaClass
对象;这次 HandleMetaClass
持有的不是 MetaClassImpl
,而是 ExpandoMetaClass
。
看下面的截图,
现在,回答你的问题,this.metaClass
是一个特例,就像 this
本身一样。它不会为您提供 HandleMetaClass
对象的句柄,因此您不能直接扩展 this
的 metaClass
;并且这也没有任何意义,因为所有其他未来实例都将共享该扩展。
如果你真的想要那种行为,那么你可以将 this
传递给其他一些变量,即 instance = this
,就像你在构造函数中所做的那样,然后你可以扩展 instance
-- 并且该扩展对于 this
和所有其他未来实例都是正确的。但是,为什么不首先将行为添加到 class 本身。为什么要扩展?