Groovy探索之反射

我们知道,在Java语言中,我们能够获取到Java语言的动态性,主要是通过它的反射机制来实现的。而在Groovy语言中,我们将会有很多方式来获取它的动态性,比如MOP等等。因此,在Groovy语言中,我们需要在运行期内调用某个方法,将不会使用反射机制,虽然我们仍然能够在Groovy语言中使用反射机制来达到目的;而是使用MOP机制,或者使用"duck type"。因为这些机制都比反射来得方便和灵活。

这是否说明,我们在Groovy语言的程序开发过程中将不再使用到反射机制呢?我们说,反射机制除了能够让我们在运行期内动态的调用方法以外,还有一个很重要的功能是自省功能,就是让我们能够在运行期内知道一个对象它本身的一个信息,如属于哪个Class,有哪些属性和方法,它的Class是继承了哪个父类,还是实现了哪些接口,等等。当然,还有一个很重要的功能是,能够在运行期内实例化一个类,这也是我们经常要用到的。

因此,在我们的Groovy语言编码过程中,反射机制仍然将扮演很重要的角色,MOP机制只是将反射机制的一些很弱的功能进行了扩展。

首先,我们有一个简单的类:

package reflect;
class Testor3 {
public a
def b
private String c
}

我们已经获得了一个对象,如下所示:


def t = new Testor3()

现在,我们想知道该对象"t"的类名,在Java语言中,我们必须这样获取:

println t.getClass().getName()

在Groovy语言中,由于我们广泛的使用了Gpath,上面的语句当然可以简化成下面的样子:

println t.class.name

上面的两条语句都将打印如下的结果:

reflect.Testor3

如果我们只想获取该对象的Class名,而不想带着包名,那么将是如下的样子:

println t.class.simpleName

打印的结果为:

Testor3

值得注意的是,虽然使用Gpath来获取Class相当简单,但也不是任何时候都可以这样获取的。比如:

def map = [:]
println map.class

它的打印结果将是:

null

如果你有下面的语句:

println map.class.simpleName

那么,运行它,你将得到一个空指针的违例。

在这个时候,"getClass"方法仍将派上用场:

println map.getClass()
println map.getClass().simpleName
println map.getClass().name

上面的语句都能够正确运行,得到的结果为:

class java.util.LinkedHashMap
LinkedHashMap
java.util.LinkedHashMap

得到了对象的Class以后,我们接着想得到的是它的属性。获取对象的属性有两个方法:一是获取"fields";二是获取"declaredFields"。前一个方法能够获取到该对象的公有属性;后一个方法获取的对象的所有属性。如:

def t = new Testor3()

def cls = t.class
println cls.fields
println cls.declaredFields

运行结果为:

{public java.lang.Object reflect.Testor3.a, public static java.lang.Long reflect.Testor3.__timeStamp}
{public java.lang.Object reflect.Testor3.a, private java.lang.Object reflect.Testor3.b, private java.lang.String reflect.Testor3.c, transient groovy.lang.MetaClass reflect.Testor3.metaClass, public static java.lang.Long reflect.Testor3.__timeStamp, static java.lang.Class reflect.Testor3.class$groovy$lang$MetaClass, static java.lang.Class reflect.Testor3.class$org$codehaus$groovy$runtime$ScriptBytecodeAdapter, static java.lang.Class reflect.Testor3.class$0}

时间: 2024-11-03 09:03:11

Groovy探索之反射的相关文章

Groovy探索 自定义Range 二 自定义Range类与Decorate模式

Decorate模式相信大家都比较熟悉了,是一个"BangOfFour"中最常用的模式之一,实现起来也相当的简单.如果有人不熟悉的话,可以看看<Groovy探索之Decorate模式>,那里面有一个本篇要沿用的例子. 这个例子就是咖啡馆里买咖啡的经典例子,咖啡有原味咖啡,还有根据顾客口味不同进行各种添加,比如加冰.加奶和加糖等等.顾客可以选择不加.加一样或加多样,各种加法的咖啡所买的价格也不一样. 这个例子是Decorate模式实现的最经典的例子.我们在这里希望使用自定义R

Groovy探索 自定义Range 三 自定义Range与责任链模式

责任链模式也是我们比较常用的一种模式,我在<Groovy探索之责任链模式>中有个探索.大家也可以在网上搜索,应该有很多这方面的文章. 在这里,我们将使用自定义的Range类来实现责任链模式,使用的例子还是在<Groovy探索之责任链模式>一文中所谈到的"孙悟空大战二郎神"的这个情节.这样,我们可以把这两篇的文字结合起来看,使得我们能够对比这两种开发方式.使得我们能够深入的理解自定义Range类的使用. 在"孙悟空大战二郎神"这个情节里,重点讲

Groovy探索 关于方法名的DSL

Groovy语言最引以为豪的特点就是DSL了,关于DSL的定义以及分类.优点等,就不是本篇所要阐述的了,大家可以上网查,网上有大量的这方便的介绍.Groovy语言是非常便于设计内部DSL了,在这方面,我的Groovy探索系列已经有了很多专题谈到过使用Groovy语言创建内部DSL的一些方面.本篇所要探索的是一个关于Groovy语言DSL的一个非常小的方面.也是非常不起眼的方面:关于方法名的DSL. 说到方法名的DSL,其实我们在Groovy语言中已经有了非常广泛的应用.比如,我们在一开始学习Gr

Groovy探索之MOP 十五 方法名的动态性

到目前为止,我们的<Groovy探索之MOP>系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法.即我们添加一个方法名为A的方法,然后才能使用这个方法A. 然而,方法名的动态性,其实是我们早已接触过的事情,比如在<Groovy探索之invokeMethod方法>里,我们就可以创建形如"sortByXxxxx()&q

Groovy探索之MOP 十三 Interceptor 三(2)

其实,阻止拦截的使用像在<Groovy探索之MOP 十三 Interceptor 三(1)>中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器.还是上一篇的那个例子: class Hello { def hello(name) { "hello,$name" } } 我们现在明确的把类中所有的方法进行拦截,拦截器如下: class AllInterceptor implements Interceptor{ Object beforeInvo

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

我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法.如,我们可以在类里直接实现方法:我们可以通过ExpandoMetaClass在运行期内添加方法:我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法. 所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的.所以,我们可以说,系统是优先调用hook的. 而hook的调用顺序,我们在上一篇<Groovy探索之MOP 十一 运行期内覆盖invokeMethod>已经谈到过了.

Groovy探索之MOP 十一 运行期内覆盖invokeMethod

我们很早就会使用Groovy语言的hook,即"invokeMethod"方法和其他的几个方法.我们会在一个类中实现"invokeMethod"方法,用来分派所有的或部分的在运行期内调用的该类实例的方法.这些我们在<Groovy探索之MOP 一 invokeMethod和methodMissing方法>已经详细的谈到过. 现在,我们已经深入的接触到了Groovy语言的MetaClass,更是也到处使用到了ExpandoMetaClass.我们都已经知道,

Groovy探索之MOP 十 Interceptor 二

在本系列的<Groovy探索之MOP 九 Interceptor 一>中,我们已经详细的介绍了一个简单的拦截器类的方方面面,使得我们初步有了拦截器的基础.本篇需要在前面的拦截器类的基础上,进一步用拦截器类来实现我们的AOP编程. 首先,我们在本系列的第一篇中,所拦截的方法都是固定的方法.现在,我们需要把它扩展成由拦截器类的使用者来指定被拦截的方法. 先还是给出需要被拦截的类来: class Foo { def test1() { println 'test1' } def test2() {

Groovy探索之MOP 一 invokeMethod和methodMissing方法

终于要谈到Groovy语言的MOP特性了,我在前面的章节中零星的谈到了它,却始终没有系统的来谈到它.这是因为Groovy语言的MOP特性实在是太灵活了,比如本章节要谈到的"invokeMethod"和"methodMissing"方法,它们的功能有很大的相似之处,而区别却相当的微妙.但是,不管怎么样,Groovy语言的MOP编程都是我们必须掌握的.而这个系列我没有计划多少个部分谈完,跟<Groovy探索之闭包>系列一样,探索一部分说一部分. 本节要谈到的