基于JVM的动态语言Groovy MetaProgramming 知识集

简介: Metaprogramming 使groovy动态语言的特性发挥的淋漓尽致(Metaprogramming is writing code that has the ability to dynamicallychange its behavior at runtime.

Metaprogramming 使groovy动态语言的特性发挥的淋漓尽致(Metaprogramming is writing code that has the ability to dynamicallychange its behavior at runtime.)

如下是这方面的知识一个汇总

1. 类Discovering the Class

def s = "Hello"

printlns.class

printlns.getClass()

String.constructors.each{println it}

println ""

String.interfaces.each{println it}

println ""

2. 域Discovering the Fields of a Class

def d = new Date()

printlnd.properties

println ""

d.properties.each{println it}

println ""

d.class.declaredFields.each{println it}

println ""

//重要的对象metaClass

printlnDate.metaClass

3. 域存在性检查Checking for the Existence of a Field

class Person{

String firstname

String lastname

String toString(){"${firstname} ${lastname}"}

MetaPropertyhasProperty(String property){

return this.metaClass.hasProperty(this, property)

}

}

def person = new Person()

def request = [firstname: "bill", lastname: "gates"]

request.each{name, value->

if(person.metaClass.hasProperty(person, name)){

//if(person.hasProperty(name)){

person.setProperty(name, value)

}

}

println person

4. 方法Discovering the Methods of a Class

def d = new Date()

d.class.methods.each{println it}

d.class.methods.name

println ""

//evaluate run in a new shell

d.class.methods.each{method ->

if(method.name.startsWith("get")){

print "${method.name}: "

evaluate("dd = new Date(); println dd.${method.name}()")

}

}

println ""

//

def binding = new Binding()

binding.setVariable("d", d)

defgs = new GroovyShell(binding)

d.class.methods.each{method ->

if(method.name.startsWith("get")){

print "${method.name}: "

gs.evaluate("println d.${method.name}()")

}

}

println ""

//GString (most concise way to dynamically call a method on a class)

d.class.methods.each{method ->

if(method.name.startsWith("get")){

print "${method.name}: "

println d."${method.name}"()

}

}

println ""

5. 方法存在性检查Checking for the Existence of a Method

class Greeting{

defsayHello(){

println "Hello, Stranger"

}

defsayHello(String name){

println "Hello, ${name}"

}

}

def g = new Greeting()

if(g.metaClass.respondsTo(g, "sayHello", null)){

g.sayHello()

}

if(g.metaClass.respondsTo(g, "sayHello", String)){

g.sayHello("Jane")

}

println "Number of sayHello() methods: " + g.metaClass.respondsTo(g, "sayHello").size()

g.metaClass.respondsTo(g, "sayHello").each{m ->

println "${m.name} ${m.nativeParameterTypes}"

}

6. 域指针Creating a Field Pointer

def p = new Person()

p.name = "Jane"

println p.name

//Field Pointer, 可以操作privtate

printlnp.@name

7. 方法指针Creating a Method Pointer

def list = []

def insert = list.&add

insert "Java"

insert "Groovy"

println list

8. Calling Methods That Don’t Exist (invokeMethod)

class Person{

String name

Map relationships = [:]

Object invokeMethod(String what, Object who){

if(relationships.containsKey(what)){

who.each{thisPerson ->

relationships.get(what).add(thisPerson)

}

}

else{

relationships.put(what,who as List)

}

}

}

defscott = new Person(name:"Scott")

scott.married "Kim"

scott.knows "Neal"

scott.workedWith "Brian"

scott.knows "Venkat"

scott.workedWith "Jared"

scott.knows "Ted", "Ben", "David"

printlnscott.relationships

9. Creating an Expando

def e = new Expando()

e.latitude = 70

e.longitude = 30

println e

e.areWeLost = {->

return (e.longitude != 30) || (e.latitude != 70)

}

printlne.areWeLost()

10. Adding Methods to a Class Dynamically (Categories)

Categories allow you to add new functionality to any class at runtime.

use(RandomHelper){

10.times{ println 10.rand() }

}

class RandomHelper{

static int rand(Integer self){

def r = new Random()

return r.nextInt(self.intValue())

}

}

use(InternetUtils){

println "http://localhost/".get()

println "http://search.yahoo.com/search".get("p=groovy")

defparams = [:]

params.n = "10"

params.vl = "lang_eng"

params.p = "groovy"

println "http://search.yahoo.com/search".get(params)

}

class InternetUtils{

static String get(String self){

return self.toURL().text

}

static String get(String self, String queryString){

defurl = self + "?" + queryString

return url.get()

}

static String get(String self, Map params){

def list = []

params.each{k,v->

list << "$k=" + URLEncoder.encode(v)

}

defurl = self + "?" + list.join("&")

return url.get()

}

}

11. Adding Methods to a Class Dynamically(ExpandoMetaClass)

Integer.metaClass.rand = {->

def r = new Random()

return r.nextInt(delegate.intValue())

}

5.times{ println 10.rand() }

String.metaClass.get = {->

return delegate.toURL().text

}

println "http://localhost/".get()

 

A category is perfect ifyou want to limit the scope of your new methods to a well-defined blockof code. An ExpandoMetaClass is better if you want to have your newmethods applied to all instances across the entire running application.

If you want your new functionality to be easily shared by both Java andGroovy code, categories leave you with a plain old Java class with staticmethods. ExpandoMetaClasses are more closely tied to Groovy, but theyare significantly more performant as well.

以上可以作为使用的一个参考,在使用反射等这类应用时,使用groovy可以很大的简化开发

相关文章
|
Java 关系型数据库 数据库连接
基于JVM的动态语言Groovy 基础知识汇总
在使用Java的过程中,和C#的语法相比有些还是比较麻烦,比如异常、get set等问题,毕竟Java的发展时间比C#长了很多,很多问题当初设计时没有考虑到,为了向前兼容,不得不保留一定的历史负担(如泛型的处理,java的擦除法实现就是后续的兼容考虑)。
1330 0
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
1067 55
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
1059 6
|
9月前
|
存储 缓存 Java
我们来说一说 JVM 的内存模型
我是小假 期待与你的下一次相遇 ~
582 5
|
9月前
|
存储 缓存 算法
深入理解JVM《JVM内存区域详解 - 世界的基石》
Java代码从编译到执行需经javac编译为.class字节码,再由JVM加载运行。JVM内存分为线程私有(程序计数器、虚拟机栈、本地方法栈)和线程共享(堆、方法区)区域,其中堆是GC主战场,方法区在JDK 8+演变为使用本地内存的元空间,直接内存则用于提升NIO性能,但可能引发OOM。
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
2817 1
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
1383 166
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
794 29
JVM简介—1.Java内存区域
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
存储 算法 Java
JVM: 内存、类与垃圾
分代收集算法将内存分为新生代和老年代,分别使用不同的垃圾回收算法。新生代对象使用复制算法,老年代对象使用标记-清除或标记-整理算法。
267 6