`
jimichan
  • 浏览: 280612 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

groovy MetaClass 剖析 1

阅读更多

<!----><!---->

本篇介绍groovy 的MetaClasses ,MetaClass 是Groovy 动态编程比较重要的组成。

(以下出现的代码片段是在groovy1.5.3测试通过,希望各位可以运行之)。

 

1.MetaClass

           groovy中出现的每个类都有其对应的MetaClass。MetaClas是一个接口,该接口扩展了MetaObjectProtocol接口,这就是我们通常所说的MOP协议了。

MetaClass的实现类主要有 

 

 

MetaClassImpl 是通用的实现类。ClosureMetaClass是闭包类特有的MetaClass。ExpandoMetaClass是用户扩展groovy类行为时用到的MetaClass

 

println 'first:---> '+'test'.metaClass

println 'String.metaClass:---> '+String.metaClass

println 'after String.metaClass:--->  '+'test'.metaClass

 

执行结果为
first:---> groovy.lang.MetaClassImpl@183f74d[class java.lang.String]
String.metaClass:---> groovy.lang.ExpandoMetaClass@8a0d5d[class java.lang.String]
after String.metaClass:--->  groovy.lang.ExpandoMetaClass@8a0d5d[class java.lang.String]

 对于这样的结果你是不是会感觉到奇怪呢?

下面我将结合Groovy实现代码来解释这个过程

第一句脚本 通过String实例对象来获得,Groovy为其初始化的groovy.lang.MetaClassImpl@183f74d[class java.lang.String]对象。这个对象将在MetaClassRegistryImpl中和String类关联起来。也就是注册了String.class和

groovy.lang.MetaClassImpl的对象关系。

第二句脚本 通过String类去访问 metaClass对象,不过这一次是调用了类DefaultGroovyMethods中的方法

 

    /**
     * Adds a "metaClass" property to all class objects so you can use the syntax
     * <code>String.metaClass.myMethod = { println "foo" }</code>
     *
     * @param c The java.lang.Class instance
     * @return An MetaClass instance
     */
    public static MetaClass getMetaClass(Class c) {
        MetaClassRegistry metaClassRegistry = GroovySystem.getMetaClassRegistry();
        MetaClass mc = metaClassRegistry.getMetaClass(c);
        if (mc instanceof ExpandoMetaClass
                || mc instanceof DelegatingMetaClass && ((DelegatingMetaClass) mc).getAdaptee() instanceof ExpandoMetaClass)
            return mc;
        else {
            MetaClass emc = ExpandoMetaClassCreationHandle.instance.create(c, metaClassRegistry);
            emc.initialize();
            metaClassRegistry.setMetaClass(c, emc);//并且在metaClassRegistry中注册
            return emc;
        }
    }

 第三句脚本又重新通过String实例对象来获得了,但这一次得到的是groovy.lang.ExpandoMetaClass@8a0d5d,这是因为第二句话中对String和其MetaClass对象进行了重新注册。

自此以后系统中所有的String对象的MetaClass对象都一直市是ExpandoMetaClass对象实例。

 

 

由于我们举的String例子有点特殊

我们看看对于自定义类的例子

class Foo{
	
}
def f1 = new Foo();
println f1.metaClass

println Foo.metaClass

println f1.metaClass

def f2 = new Foo()
println f2.metaClass

 结果是不是又不一样了?

f1对象的metaClass是被缓存了,只有在调用过

Foo.metaClass

 之后,new出来的对象才会使用ExpandoMetaClass

 

 

2
0
分享到:
评论
6 楼 jimichan 2008-11-11  
就我所知,系统类如内置数组类的处理方式是不一样的
5 楼 bloodwolf_china 2008-11-07  
那为什么'test'的metaClass没有被缓存,f1 = new Foo(); f1对象的metaClass就
缓存呢?
'test'.metaClass --MetaClassImpl
String.metaClass --ExpandoMetaClass
'test'.metaClass --ExpandoMetaClass

f1 = new Foo();
f1.metaClass --MetaClassImpl
Foo.metaClass --ExpandoMetaClass
f1.metaClass --MetaClassImpl
系统类和自定义类处理不一样?
4 楼 RayChase 2008-10-27  
好久了吧 剖析2还没出啊 呵呵
3 楼 jimichan 2008-09-25  
最近觉得学习这个语言的话,没有太多必要研究底层如何实现的
2 楼 RayChase 2008-09-21  
期待剖析2
1 楼 RayChase 2008-09-21  
有收获!

相关推荐

    Groovy MOP

    1. **MetaClass**: MetaClass是Groovy MOP的核心,它是任何Groovy对象的元数据容器。MetaClass存储了对象的方法、属性以及如何调用这些方法和属性的信息。你可以为任何对象或类动态地替换其MetaClass,从而改变其...

    Groovy in Action源代码

    通过源代码,你可以看到如何使用MetaClass、ExpandoMetaClass等来扩展类的功能,实现动态属性和方法。 4. **GString与模板引擎**:Groovy的GString能方便地进行字符串插值,源代码中可能会包含使用GString构建动态...

    groovy学习资料

    - `MetaClass`是Groovy元编程的核心,它提供了修改类行为的接口。 8. **学习Groovy的资源** - 提供的"groovy学习资料"和"groovy入门资料"可能是文档或PDF教程,这些资源可以帮助初学者快速了解Groovy的基础知识和...

    spock-hidden-gems

    2. **元类和混入(Metaclass and Mixins)**: Groovy 的元类系统在 Spock 中发挥了重要作用。你可以定义元类方法,用于扩展或修改测试对象的行为。混入(Mixins)则允许你将多个类的方法组合到一个类中,这在创建...

    Android 多渠道打包 Walle 测试版本

    packageInfo = context.getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA); return packageInfo.metaData.getString("channelId"); } catch (PackageManager....

    met_objects

    5. **元类(MetaClass)**:在Groovy等JVM语言中,存在元类的概念,它扩展了Java的反射机制,允许更动态地操作类和对象。虽然这不是Java的标准特性,但在处理动态语言时,理解元类是必要的。 6. **注解处理...

    《kettle中访问前一行数据》示例附件

    1. **前向查找与前一行数据访问** Kettle中的Step(步骤)可以访问并处理来自上游步骤的数据,这得益于它的流式处理特性。通过使用特定的字段或变量,我们可以访问前一行的数据。例如,你可以使用"Previous row...

    java工程文件

    - **Gradle**:基于Groovy语言编写,提供更灵活的配置方式,并且支持增量构建,提高构建效率。 ### 自带调试结果的Java工程 根据题目描述,“自带调试结果”,意味着该项目已经经过了初步的调试,并且可能附带了...

    BuglyDemo代码

    然后,将这个AppID引入到你的应用中,这通常涉及到在AndroidManifest.xml或者Info.plist(iOS)文件中配置相应的 meta-data 或 key。 对于Android应用,你需要在Gradle构建脚本中添加Bugly的依赖库,并在应用初始化...

    ansj所需jar及library

    1. **MANIFEST.MF文件指定**: 如果你正在使用传统的Java应用程序或者JavaFX项目,可以编辑`META-INF/MANIFEST.MF`文件,在`Class-Path`字段中添加jar文件的路径。 2. **IDE集成**: 对于Eclipse、IntelliJ IDEA等...

    android百度云实现消息推送

    public class PushReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(BaiduPushConstants.MESSAGE_ACTION)) { // 消息...

    Android Studio多渠道批量打包及代码混淆

    1. **配置多渠道**: 在`AndroidManifest.xml`中,通过添加`&lt;meta-data&gt;`标签,设置友盟或其他统计工具的渠道标识,如`&lt;meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL_VALUE}"/&gt;`。这里的`${...

    基于百度地图实现的定位功能.zip

    在Android开发中,实现基于...通过分析提供的源码,你可以更深入地了解每个细节,包括地图的显示、定位标记的更新、位置信息的解析等,从而提升你的Android开发技能。记得遵守开源和版权规定,合理使用和分享学习资源。

    android 百度地图

    `BaiduMapsApiDemo`项目包含了上述所有功能的完整示例,你可以通过运行和分析代码,更深入地理解和学习如何在实际应用中使用百度地图API。该项目中的每个示例都对应一个特定的地图功能,例如定位、标注、热力图、...

    FirbaseCrashReport:存取资料的关键

    1. **集成 Firebase SDK**:首先,你需要在项目中添加 Firebase SDK。这可以通过在 `build.gradle` 文件中添加相应的依赖来完成。对于 Android 项目,需要在 `dependencies` 部分引入 Firebase Crash Reporting 库。...

    MappAndroidprj.rar_android开发_Java_

    通过学习和分析"MappAndroidprj"项目,你不仅能够掌握Android中集成Google Maps的基本步骤,还能了解到如何利用Java处理地图相关的复杂任务,从而提升你的Android开发技能。记得不断实践和探索,才能更好地理解和...

Global site tag (gtag.js) - Google Analytics