Android Groovy 对象和方法拦截(十一)

首先申明下,本文为笔者学习《Groovy 程序设计》的笔记,并加入笔者自己的理解和归纳总结。

1. Groovy对象

在一个Groovy应用中,使用三类对象,POJO(普通Java对象)、POGO(Groovy对象,实现GroovyObject接口)和Groovy拦截器(实现GroovyInterceptable)。

GroovyObject接口

package groovy.lang;

public interface GroovyObject {
    Object invokeMethod(String name, Object args);
    Object getProperty(String propertyName);
    void setProperty(String propertyName, Object newValue);
    MetaClass getMetaClass();
    void setMetaClass(MetaClass metaClass);
}

GroovyInterceptable接口

package groovy.lang;

public interface GroovyInterceptable extends GroovyObject {
}

2. Groovy方法调用顺序

2.1 POJO调用顺序

MetaClass上的方法优于原先的方法。

def val = 3
println val.toString() // 3

Integer.metaClass.toString = { -> "Integer toString" }
println val.toString() // Integer toString

2.2 GroovyInteceptable调用顺序

不管方法存不存在,都会调用invokeMethod()方法。不能使用println()方法,同样会被拦截。

class AnInterceptable implements GroovyInterceptable {
    def add(val1, val2) {
        val1 + val2;
    }

    // println方法同样会被拦截
    public Object invokeMethod(String name, args) {
        System.out.println(name)
        System.out.println(args.join(" "))
    }
}

def interceptable = new AnInterceptable()
interceptable.add(13, 17)
interceptable.nonExistingMethod("hello")

返回

add
13 17
nonExistingMethod
hello

2.3 GroovyObject调用顺序

首先查看方法是否存在MetaClass或原有类中。

class AGroovyClass {
    def fun() {
        println "fun"
    }
    def methodMissing(String name, args) {
        println "methodMissing " + name
    }
}

obj = new AGroovyClass()
obj.fun() // fun
obj.nonExistingMethod() // methodMissing nonExistingMethod
obj.metaClass.nonExistingMethod = { -> println "nonExistingMethod" }
obj.nonExistingMethod() // nonExistingMethod

如果方法不存在,查看是否存在该名称的属性,属性是否为闭包

class AGroovyClassWithClosure {
    def fun = { -> println "fun closure" }
    def paramClosure = { -> println "parameter closure" }

    def fun() {
        println "fun"
    }
    def methodMissing(String name, args) {
        println "methodMissing " + name
    }
}

obj = new AGroovyClassWithClosure()
obj.fun() // fun

def fun = obj.fun
fun() // fun closure

obj.paramClosure() // parameter closure

obj.nonExistingMethod() // methodMissing nonExistingMethod

查看是否有methodMissing()方法

class AGroovyClassWithInvokeAndMissingMethod {
    def methodMissing(String name, args) {
        println "methodMissing " + name
    }
    def invokeMethod(String name, args) {
        println "invokeMethod " + name
    }
}

obj = new AGroovyClassWithInvokeAndMissingMethod()
obj.nonExistingMethod() // methodMissing nonExistingMethod

查看invokeMethod()方法。

class AGroovyClassWithOnlyInvokeMethod {
    def invokeMethod(String name, args) {
        println "invokeMethod " + name
    }
}

obj = new AGroovyClassWithOnlyInvokeMethod()
obj.nonExistingMethod() // invokeMethod nonExistingMethod

3. 方法拦截

Groovy对象可以通过实现GroovyInterceptable接口来实现拦截,因为每个方法都会先调用invokeMethod()方法。

class AnInterceptable implements GroovyInterceptable {
    def add(val1, val2) {
        val1 + val2
    }

    public Object invokeMethod(String name, args) {
        System.out.println("invokeMethod: " + name)
        def method = AnInterceptable.metaClass.getMetaMethod(name, args)
        if (method) {
            method.invoke(this, args)
        } else {
            System.out.println("no method find: " + name)
        }
    }
}
obj = new AnInterceptable()
println obj.add(11, 13)
println obj.add("Hello ", "World!")
obj.add()
obj.nonExistingMethod()

返回

invokeMethod: add
24
invokeMethod: add
Hello World!
invokeMethod: add
no method find: add
invokeMethod: nonExistingMethod
no method find: nonExistingMethod

对于POJO和部分POGO类来说,无法修改原始类,使用MetaClass类的invokeMethod()方法。

class AGroovyClass {
    def add(val1, val2) {
        val1 + val2
    }
}
AGroovyClass.metaClass.invokeMethod = { name, args ->
    System.out.println("invokeMethod: " + name)

    method = AGroovyClass.metaClass.getMetaMethod(name, args);
    if (method) {
        method.invoke(delegate, args)
    } else {
        System.out.println("no method find: " + name)
    }
}
obj = new AGroovyClass()
println obj.add(11, 13)
println obj.add("Hello ", "World!")
obj.add()
obj.nonExistingMethod()

返回

invokeMethod: add
24
invokeMethod: add
Hello World!
invokeMethod: add
no method find: add
invokeMethod: nonExistingMethod
no method find: nonExistingMethod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值