Gradle入门之Groovy元编程
Posted 我就是马云飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gradle入门之Groovy元编程相关的知识,希望对你有一定的参考价值。
简介
Groovy的元编程是指groovy运行时,可以理解成编写代码所执行的时期,也就是Runtime。在比如有解释执行的Js,编译执行的java,还有运行时期执行的代码java反射。
Groovy运行时的处理逻辑如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i4GhgXKL-1611849711349)(https://s3.ax1x.com/2021/01/14/sdrfyj.png)]
元编程
按照上图所示,我们可以自己写一个Demo,示例代码如下:
class Study
public static void main(String[] args)
def person = new Personal(name: "Silence", age: 26)
println(person.printName())
println(person.printAge())
println(person.sex)
class Personal
public String name
public int age
public String printName()
return "My name is $name"
public String printAge()
return "My ag is $age"
输出结果如下:
My name is Silence
My ag is 26
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: sex for class: Personal
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:65)
at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:87)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:329)
at Study.main(Study.groovy:9)
可以看到前两个日志是正常输出的,第三个控制台则提示MissingPropertyException。也就是上图中,所以逻辑都没进去导致异常输出。
我们在看看如果我们复写invokeMethod方法时的输出效果,代码修改如下:
class Personal
public String name
public int age
public String printName()
return "My name is $name"
public String printAge()
return "My ag is $age"
@Override
Object invokeMethod(String name, Object args)
return "this invoke method is $name,this params is $args"
控制台输出如下:
My name is Silence
My ag is 26
this invoke method is sex,this params is []
然后我们看看重写methodMissing方法后:
class Personal
public String name
public int age
public String printName()
return "My name is $name"
public String printAge()
return "My ag is $age"
@Override
Object invokeMethod(String name, Object args)
return "this invoke method is $name,this params is $args"
Object methodMissing(String name, Object args)
return "this Missing method is $name,this params is $args"
输出结果如下:
My name is Silence
My ag is 26
this Missing method is sex,this params is []
可以看出,两个方法都重写时,优先调用methodMissing。如果找不到才会调用invokeMethod。
MetaClass
Metaclasses在方法解析中起到核心作用,对于来自groovy代码的每个方法调用,Groovy将找到给定对象的MetaClass,并通过MetaClass#invokeMethod将方法解析委托给Metaclasses,不应该与GroovyObject#invokeMethod混淆,后者恰好是Metaclasses最终可能调用的方法。
注入新字段
现在我们通过metaClass给Personal注入一个新属性看看:
Personal.metaClass.sex = "男"
def person = new Personal(name: "Silence", age: 26)
println(person.printName())
println(person.printAge())
println(person.sex)
可以看出我们注入了一个sex的字段,输入结果如下:
My name is Silence
My age is 26
男
当然了,注入静态变量也是类似,加上static即可。
注入新方法
看到我们输入性别的时候,发现好像和上面对比,不工整,那就自己整一个工整的,修改代码:
Personal.metaClass.sex = "男"
Personal.metaClass.printSex = ->
"My sex is $sex"
def person = new Personal(name: "Silence", age: 26)
println(person.printName())
println(person.printAge())
println(person.printSex())
输出结果可想而之:
My name is Silence
My age is 26
My sex is 男
这下工整了~。当然了,注入静态方法也是类似,加上static即可。
总结
可以看出,我们可以通过metaClass给类新增变量,新增方法。那么这个和直接在类这种提供有什么区别呢?
举个例子:引入第三方库,其中的某个类有我们想用的方法,但是这个方法又不够全,想给里面添加点自己的方法。通常是extends它进而扩展,但是如果是final 类,任何类不能继承它,只能用它已有的方法。这个时候groovy的动态添加就有了大展身手的地方。不修改、不继承,通过metaclass变相的对原有的类进行了扩展。
参考
本文首发于我的个人博客:Gradle入门之Groovy元编程
更多文章请关注我的公众号:码农职场
以上是关于Gradle入门之Groovy元编程的主要内容,如果未能解决你的问题,请参考以下文章
Android Gradle 插件Gradle 构建工具简介 ③ ( Gradle 构建脚本编程语言 | Groovy 语言简介 | Groovy 语言特性 )