Groovy探索之MOP 十二 方法的调用顺序

Groovy探索之MOP 十二 方法的调用顺序,第1张

概述               Groovy探索之MOP 十二 方法的调用顺序     我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法。如,我们可以在类里直接实现方法;我们可以通过ExpandoMetaClass在运行期内添加方法;我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法。 所有的这些直接添加方法的途径,如果存在hook的话,都是要被

               Groovy探索之MOP 十二 方法的调用顺序

 

 

我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法。如,我们可以在类里直接实现方法;我们可以通过ExpandoMetaClass在运行期内添加方法;我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法。

所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的。所以,我们可以说,系统是优先调用hook的。

而hook的调用顺序,我们在上一篇《Groovy探索之MOP 十一 运行期内覆盖invokeMethod》已经谈到过了。

本篇要谈到,却是除了hook方法以外的方法实现途径的调用顺序的问题。

我们都知道,如果有如下的一个类:

 

class Foo {

   

    def getFoo()

    {

       'foo'

    }

   

 

}

 

 

那么,我们可以通过如下的方法来调用它的方法:

     

 

      def foo = new Foo()

     

      println foo.foo

   

 

运行结果为:

foo

 

这就是我们的Gpath。

当然,我们也可以通过ExpandoMetaClass在运行期内添加这个"get"方法,如下:

 

      Foo.MetaClass.getFoo = {

             ->

               'Meta'

      }

 

 

如果我们再做下面的测试:

 

 

      def foo = new Foo()

     

      println foo.foo

   

 

 

那么,运行结果为:

Meta

 

从结果可以看出,在运行期内通过ExpandoMetaClass添加的方法是会覆盖类本身的方法的。

我们知道,在运行期内给类添加方法还有一种方式,即:

 

      def mc = new ExpandoMetaClass(Foo.class,true)

     

      mc.getFoo = {

       ->

           'far'

      }

     

      mc.initialize()

 

 

下面,我将对上面的Foo类,在运行期内同时实行上面的两种方法的添加方式,然后在做测试,看看结果将会如何?

代码如下:

     

      Foo.MetaClass.getFoo = {

             ->

               'Meta'

      }

 

      def mc = new ExpandoMetaClass(Foo.class,true)

     

      mc.getFoo = {

       ->

           'far'

      }

     

      mc.initialize()

     

 

      def foo = new Foo()

      println foo.foo

   

  }

 

 

运行结果为:

far

 

由此可见,后一种在运行期内添加方法的方式是会覆盖前一种在运行期内添加方法的方式的。

除此之外,我们还有一种在运行期内给对象添加方法的方式,如下:

def emc = new ExpandoMetaClass( foo.class,false )

      emc.getFoo = {

           ->

              "test" }

      emc.initialize()

  foo.MetaClass = emc

 

 

最后,我们还将写代码来测试这最后一种方式与前几种方式的调用顺序。代码如下:

 

      def mc = new ExpandoMetaClass(Foo.class,true)

     

      mc.getFoo = {

       ->

           'far'

      }

     

      mc.initialize()

     

 

      def foo = new Foo()

 

      def emc = new ExpandoMetaClass( foo.class,false )

      emc.getFoo = {

           ->

              "test" }

      emc.initialize()

      foo.MetaClass = emc

     

      println foo.foo

   

 

 

运行结果为:

test

 

 

可以看出,使用上面的方式在运行期内给一个对象添加的方法,会覆盖通过ExpandoMetaClass在运行期内给一个类添加的方法。

总结

以上是内存溢出为你收集整理的Groovy探索之MOP 十二 方法的调用顺序全部内容,希望文章能够帮你解决Groovy探索之MOP 十二 方法的调用顺序所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1271027.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存