首先申明下,本文为笔者学习《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