我使用虚拟Employee groovy类编写了以下测试。
@Test
void returnPropertyIfPropertyIsAvailableOnMetaClass(){
def emp=new Employee()
emp.metaClass.sayGutenAbend="Guten Abend"
assert emp.sayGutenAbend=="Guten Abend"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend")
emp.metaClass.setProperty(emp,"sayGutenAbend","Guten Morgen")
assert emp.sayGutenAbend=="Guten Morgen"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend");
}
以下测试通过,而以下失败 -
@Test
void returnPropertyIfPropertyIsAvailableOnMetaClass_Fails(){
def emp=new Employee()
emp.metaClass.sayGutenAbend="Guten Abend"
assert emp.sayGutenAbend=="Guten Abend"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend")
emp.metaClass.sayGutenAbend="Guten Morgen"
assert emp.sayGutenAbend=="Guten Morgen"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend")
}
与前一代码示例的唯一区别是,在元类上为同一属性设置新值。只是好奇。谁能指出我为什么这样做?
答案 0 :(得分:1)
使用元编程创建字段后,您无需使用metaClass
重置字段:
class Employee{}
def emp = new Employee()
emp.metaClass.sayGutenAbend="Guten Abend"
assert emp.sayGutenAbend=="Guten Abend"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend")
emp.sayGutenAbend="Guten Nacht"
assert emp.sayGutenAbend=="Guten Nacht"
assert emp.sayGutenAbend==emp.metaClass.getProperty(emp,"sayGutenAbend")
我猜测这种情况是由于重新创建了元类的某些部分而发生的,而您想要的是将绑定的对象实例更改为对象实例。 This answer可能是相关的。
在此代码段中,重置属性会创建一个新的ThreadManagedMetaBeanProperty
,因此会失败:
class Employee{}
def emp = new Employee()
emp.metaClass.sayGutenAbend="Guten Abend"
def metaclass1 = emp.metaClass.properties[1]
emp.metaClass.sayGutenAbend="Guten Nacht"
def metaclass2 = emp.metaClass.properties[1]
assert metaclass1 == metaclass2 // fails
虽然这有效:
class Employee{}
def emp = new Employee()
emp.metaClass.sayGutenAbend="Guten Abend"
def metaclass1 = emp.metaClass.properties[1]
emp.sayGutenAbend="Guten Nacht"
def metaclass2 = emp.metaClass.properties[1]
assert metaclass1 == metaclass2 // works