groovy运行期间动态添加属性和方法
我们都知道,在Groovy语言中,我们可以使用MOP特性在运行期内动态添加属性或方法?/span> ? 这种添加包括两个层面的添加: 第一:是给一个类添加属性或方法。也就是说,如果我们在运行期内给一个类添加了属性或方法,那么添加了以后,所有这个类实例化的对象,都将拥有了这个属性或方法?span class="Apple-converted-space">? 使用ExpondoMetaClass在运行期内给一个类添加属性或方法是我们最最常用的一种在运行期内添加属性或方法的方法。比如,我们有如下的一个类?/span> ? class Testor1 { ? } 现在,我们就尝试着使用ExpondoMetaClass在运行期内给Testor1添加一个方法,然后来测试它?/span> ? ????? ????? def t = new Testor1() ????? ????? try ????? { ???????? println 't invoke far' ???????? t.far() ????? } ????? catch(Exception e) ????? { ???????? ????? } ? ????? Testor1.metaClass."far" = { ???????????? -> ?????????????? println 'far' ????? } ????? ????? def t1 = new Testor1() ????? ????? println 't1 invoke far' ????? t1.far() ????? ????? ????? def t2 = new Testor1() ????? ????? println 't2 invoke far' ????? t2.far() ? 测试很简单,我们在添加方法之前实例化一个Testor1对象,然后再添加方法之后实例化两个Testor1对象,分别来测试它们?/span> 结果为: t invoke far t1 invoke far far t2 invoke far far 从结果可以看出:在添加方法之前实例化的那个对象不能调?far"方法,而添加方法之后实例化的两个对象都可以调用"far"方法?/span> 这就是在运行期内给类添加方法或属性的结果?/span> 其实,使用MOP特性在运行期内给类添加属性或方法还有一种方法来实现,它就是下面的这种方法: ? ????? def t = new Testor1() ????? ????? try ????? { ???????? println 't invoke far' ???????? t.far() ????? } ????? catch(Exception e) ????? { ???????? ????? } ? ????? def mc = new ExpandoMetaClass(Testor1.class,true) ????? ????? mc.far = { ?????? -> ?????????? println 'far' ????? } ????? ????? mc.initialize() ????? ????? def t1 = new Testor1() ????? ????? println 't1 invoke far' ????? t1.far() ????? ????? ????? def t2 = new Testor1() ????? ????? println 't2 invoke far' ????? t2.far() ????? ??? ? } 就是使用ExpondoMetaClass类来实例化一个对象,?def mc = new ExpandoMetaClass(Testor1.class,true)",再给该对象添加一个方法,如: ? ????? mc.far = { ?????? -> ?????????? println 'far' ????? } ????? 然后,将这个对象实例化,?mc.initialize()"?/span> 上面代码的运行结果为?/span> t invoke far t1 invoke far far t2 invoke far far 跟一种方法的结果一样?/span> 最后,我们来看看如何给一个对象在运行期内添加属性或方法,以及它们的运行结果?/span> ? ????? def t = new Testor1() ????? ????? try ????? { ???????? println 't invoke far' ???????? t.far() ????? } ????? catch(Exception e) ????? { ???????? ????? } ????? ????? def t1 = new Testor1() ????? ????? def emc = new ExpandoMetaClass( Testor1.class,false ) ????? emc.far = { println "far" } ????? emc.initialize() ????? t1.metaClass = emc ? ????? ????? println 't1 invoke far' ????? t1.far() ????? ????? ????? def t2 = new Testor1() ????? ????? try ????? { ??????? println 't2 invoke far' ??????? t2.far() ????? } ????? catch(Exception e) ????? { ???????? ????? } ? 我们还使?def emc = new ExpandoMetaClass( Testor1.class,false )"语句来给一个对象添加属性或方法,但需要记住的是,第二个参数是"false"。接着,我们就可以添加方法了: emc.far = { println "far" } 最后,还要做两件事,就是实例化该对象,并且把该对象赋值给t1对象的metaClass属性。如?/span> emc.initialize() t1.metaClass = emc 上面代码的运行结果为?/span> t invoke far t1 invoke far far t2 invoke far (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |