<!----><!---->
本篇介绍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
分享到:
相关推荐
1. **MetaClass**: MetaClass是Groovy MOP的核心,它是任何Groovy对象的元数据容器。MetaClass存储了对象的方法、属性以及如何调用这些方法和属性的信息。你可以为任何对象或类动态地替换其MetaClass,从而改变其...
通过源代码,你可以看到如何使用MetaClass、ExpandoMetaClass等来扩展类的功能,实现动态属性和方法。 4. **GString与模板引擎**:Groovy的GString能方便地进行字符串插值,源代码中可能会包含使用GString构建动态...
- `MetaClass`是Groovy元编程的核心,它提供了修改类行为的接口。 8. **学习Groovy的资源** - 提供的"groovy学习资料"和"groovy入门资料"可能是文档或PDF教程,这些资源可以帮助初学者快速了解Groovy的基础知识和...
2. **元类和混入(Metaclass and Mixins)**: Groovy 的元类系统在 Spock 中发挥了重要作用。你可以定义元类方法,用于扩展或修改测试对象的行为。混入(Mixins)则允许你将多个类的方法组合到一个类中,这在创建...
packageInfo = context.getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA); return packageInfo.metaData.getString("channelId"); } catch (PackageManager....
5. **元类(MetaClass)**:在Groovy等JVM语言中,存在元类的概念,它扩展了Java的反射机制,允许更动态地操作类和对象。虽然这不是Java的标准特性,但在处理动态语言时,理解元类是必要的。 6. **注解处理...
1. **前向查找与前一行数据访问** Kettle中的Step(步骤)可以访问并处理来自上游步骤的数据,这得益于它的流式处理特性。通过使用特定的字段或变量,我们可以访问前一行的数据。例如,你可以使用"Previous row...
- **Gradle**:基于Groovy语言编写,提供更灵活的配置方式,并且支持增量构建,提高构建效率。 ### 自带调试结果的Java工程 根据题目描述,“自带调试结果”,意味着该项目已经经过了初步的调试,并且可能附带了...
然后,将这个AppID引入到你的应用中,这通常涉及到在AndroidManifest.xml或者Info.plist(iOS)文件中配置相应的 meta-data 或 key。 对于Android应用,你需要在Gradle构建脚本中添加Bugly的依赖库,并在应用初始化...
1. **MANIFEST.MF文件指定**: 如果你正在使用传统的Java应用程序或者JavaFX项目,可以编辑`META-INF/MANIFEST.MF`文件,在`Class-Path`字段中添加jar文件的路径。 2. **IDE集成**: 对于Eclipse、IntelliJ IDEA等...
public class PushReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(BaiduPushConstants.MESSAGE_ACTION)) { // 消息...
1. **配置多渠道**: 在`AndroidManifest.xml`中,通过添加`<meta-data>`标签,设置友盟或其他统计工具的渠道标识,如`<meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL_VALUE}"/>`。这里的`${...
在Android开发中,实现基于...通过分析提供的源码,你可以更深入地了解每个细节,包括地图的显示、定位标记的更新、位置信息的解析等,从而提升你的Android开发技能。记得遵守开源和版权规定,合理使用和分享学习资源。
`BaiduMapsApiDemo`项目包含了上述所有功能的完整示例,你可以通过运行和分析代码,更深入地理解和学习如何在实际应用中使用百度地图API。该项目中的每个示例都对应一个特定的地图功能,例如定位、标注、热力图、...
1. **集成 Firebase SDK**:首先,你需要在项目中添加 Firebase SDK。这可以通过在 `build.gradle` 文件中添加相应的依赖来完成。对于 Android 项目,需要在 `dependencies` 部分引入 Firebase Crash Reporting 库。...
通过学习和分析"MappAndroidprj"项目,你不仅能够掌握Android中集成Google Maps的基本步骤,还能了解到如何利用Java处理地图相关的复杂任务,从而提升你的Android开发技能。记得不断实践和探索,才能更好地理解和...