Groovy:this.metaClass与instance.metaClass [英] Groovy: this.metaClass Versus instance.metaClass
问题描述
我在本书中遇到了groovy脚本代码。
class Person {
def work(){
println work()
}
def sports = ['basketball','football','voleyball']
def methodMissing(String name,args){
if(name在运动中){
println将$ {name}注入Person类
Person实例= this
printlnthis.metaClass:\ t\ $ $ {this.metaClass}
printlninstance.metaClass:\ t $ {instance.metaClass}
assert this.metaClass == instance.metaClass
} else {
printlnno such method:
$ b $ new $ Person $
jack.football(
输出如下:
将足球注入Person类
this.metaClass:groovy.lang.MetaClassImpl@245b4bdc [class Person]
instance.metaClass:org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc [groovy.lang.MetaClassImpl@245b4bdc [class Person]]
Caught:断言失败:
//为简单起见,我没有粘贴详细的断言
所以我很困惑:
- 为什么this.metaClass不等于instance.metaClass?
- 更多,我不能使用this.metaClass注入新的方法; groovy告诉我this.metaClass没有这样的属性,我打算注入。
- 什么是org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc [groovy.lang.MetaClassImpl@245b4bdc [班人]]是什么意思?我知道245b4bdc可能是对象指针。但为什么HandleMetaClass和MetaClassImpl具有相同的指针值245b4bdc?
目前,我发现@ 245b4bdc不是 strong> Object reference ,所以 HandleMetaClass @ 245b4bdc 不一定与 MetaClassImpl @ 245b4bdc 相同。我们可以使用Object.is()方法来判断它们是否相同(我这样做了,结果是 false )
-
为什么this.metaClass!= instance.metaClass?
它涉及到字段的访问权限。
-
从 outside 中访问实例字段时,groovy实际上调用函数getFieldName() 。在我的示例中,当我使用 instance 时,我在外部;所以 instance.metaClass 会调用 instance.getMetaClass()。
里面,groovy只是直接访问该字段,getFieldName()不会被调用。在我们的示例中,当我使用 this 时,我处于里面;因此 this.metaClass 将直接访问 metaClass 。
最后,getMetaClass()返回一个 HandleMetaClass 对象,而内部metaClass是一个 MetaClassImpl 对象。因此 this.metaClass!= instance.metaClass 。 -
-
-
metaClass.say = { - > printlnsay}会抛出MissingPropertyException?
-
this.metaClass的类型是MetaClassImpl
-
MetaClassImpl是一个低级别的类,它支持用于注入的高级类(例如.HandleMetaClass)。这并不意味着开发人员直接使用,所以它不支持注入方式: xxxx.say = { - > printlnsay} 。
-
- why is this.metaClass not equal to instance.metaClass?
- further more, I can not use this.metaClass to inject new methods; groovy tells me this.metaClass have no such property, which I intended to inject.
- What does "org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc[groovy.lang.MetaClassImpl@245b4bdc[class Person]]" mean? I know "245b4bdc" may be the object pointer. But why HandleMetaClass and MetaClassImpl have the same pointer value "245b4bdc"?
why this.metaClass != instance.metaClass?
It involves groove's access to fields.
When accessing an instance field from "outside", groovy actually calls the function getFieldName(). In my example, when I use "instance", i am at the outside; So instance.metaClass will call instance.getMetaClass().
When accessing an instance field from "inside", groovy simply directly access the field, getFieldName() is not called. In our example, when I use "this", i am at the "inside"; So "this.metaClass" will access "metaClass" directly.
Finally, getMetaClass() returns a HandleMetaClass object while the internal metaClass is a MetaClassImpl object. So this.metaClass!=instance.metaClass.
Why this.metaClass.say={->println "say"} will throws MissingPropertyException?
this.metaClass's type is MetaClassImpl
MetaClassImpl is a low level class, which supports upper level classes(eg. HandleMetaClass) for injection. It's not meant for Developer to use directly, So it does not support the injection way: xxxx.say={->println "say"}.
代码示例(对于问题1) $ p $ class Person {
def work(){
printlnwork()
}
def sports = ['basketball','football ','voleyball']
def methodMissing(String name,args){
if(体育运动中的名字){
Person instance = this
printlnthis。 metaClass:\\\
\t $ {this.metaClass}
printlninstance.metaClass:\\\
\ $ $ {instance.metaClass}
//输出:false
printlnthis.metaClass.is(instance.metaClass):\\\
\t $ {this.metaClass.is(instance.metaClass)}
//输出:true
printlnthis.getMetaClass()。is(instance.getMetaClass()):\\\
\t $ {this.getMetaClass()。is(instance.getMetaClass())}
}其他{
printlnno这样的方法:Person类中的$ {name}()类
}
}
def jack = new Person()
jack.football()
jack.football()
代码示例(对于问题2):
class Cat {}
def a = new groovy.lang.MetaClassImpl(Cat)
try {
a。 say = { - > printlnsay}
} catch(MissingPropertyException e){
println[Fail] \\\
\tcan not the method say()into MetaClassImpl class.\\\
def b = new org.codehaus.groovy.runtime.HandleMetaClass(a)
println b
b.say = { - > println [say]}
println[确定] \\\
\tcan将方法say()放入HandleMetaClass类中\
def method = b.getMetaMethod(say)
method.invoke(this)
I have encountered below groovy script code in the book . And it generated some strange outputs to me.
class Person{
def work(){
println "work()"
}
def sports=['basketball','football','voleyball']
def methodMissing(String name, args){
if(name in sports){
println "injected ${name} into Person class"
Person instance=this
println "this.metaClass:\t\t${this.metaClass}"
println "instance.metaClass:\t${instance.metaClass}"
assert this.metaClass==instance.metaClass
}else{
println "no such method:${name}() in Person class"
}
}
}
def jack=new Person()
jack.football()
it's output is as below:
injected football into Person class
this.metaClass: groovy.lang.MetaClassImpl@245b4bdc[class Person]
instance.metaClass: org.codehaus.groovy.runtime.HandleMetaClass@245b4bdc[groovy.lang.MetaClassImpl@245b4bdc[class Person]]
Caught: Assertion failed:
//I did not paste the detailed assertion here for simplicity
So I am quite confused:
Currently, I figured out that @245b4bdc is not the "Object reference", So HandleMetaClass@245b4bdc is not necessarily the same instance as MetaClassImpl@245b4bdc. We can use Object.is() method to judge whether they are the same.(I did that, result is false)
Code Sample(For Question 1):
class Person{
def work(){
println "work()"
}
def sports=['basketball','football','voleyball']
def methodMissing(String name, args){
if(name in sports){
Person instance=this
println "this.metaClass:\n\t${this.metaClass}"
println "instance.metaClass:\n\t${instance.metaClass}"
//output: false
println "this.metaClass.is(instance.metaClass):\n\t${this.metaClass.is(instance.metaClass)}"
//output: true
println "this.getMetaClass().is(instance.getMetaClass()):\n\t${this.getMetaClass().is(instance.getMetaClass())}"
}else{
println "no such method:${name}() in Person class"
}
}
}
def jack=new Person()
jack.football()
jack.football()
Code Sample(For Question 2):
class Cat{}
def a=new groovy.lang.MetaClassImpl(Cat)
try{
a.say={->println "say"}
}catch(MissingPropertyException e){
println "[Fail]\n\tcan not inject method say() into MetaClassImpl class.\n"
}
def b=new org.codehaus.groovy.runtime.HandleMetaClass(a)
println b
b.say={->println "[say]"}
println "[OK]\n\tcan inject method say() into HandleMetaClass class\n"
def method=b.getMetaMethod("say")
method.invoke(this)
这篇关于Groovy:this.metaClass与instance.metaClass的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!