快速业务通道

Java中通过Emit实现动态类生成 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-24

Java中通过Emit实现动态类生成

时间:2010-04-27

动态生成一个类对于AOP,O/R Mapping等技术非常有帮助。对于Java来说,问题不大,而对于.NET,则要麻烦些(主要麻烦在于实现代码的生成需要IL),故猜测这可能也是在AOP, O/R Mapping方面,Java走得略前的原因吧。

麻烦归麻烦,非不能也,动态生成一个简单的类还不至于太难。

假设有如下接口:

interface IAnimal {  void move();  void eat(); }

希望能创建一个类生成器TypeCreator,并能以以下方式使用:

TypeCreator tc=new TypeCreator(typeof(IAnimal)); Type t = tc.build(); IAnimal myAnimal= (IAnimal)Activator.CreateInstance(t); myAnimal.move(); myAnimal.eat();

首先,发现System.Reflection.Emit.TypeBuilder似乎就是一个现成的类生成器。 不过TypeBuilder既没有实用的static方法,也不能在外部实例化。不过ModuleBuilder倒有一个DefineType()方法,可以得到TypeBuilder;而ModuleBuilder和TyperBuilder一个德行,不能直接创建,得从AssemblyBuilder的DefineDynamicModule()方法得到。追根溯源,AssemblyBuilder得从AppDomain的DefineDynamicAssembly()的得来。最终好在AppDomain提供了一个静态方法:AppDomain.CurrentDomain. 这一连串并非没有道理,类型是依附于Module的,而Module依附于Assembly,而Assembly则被AppDomain装载。所谓“皮之不存,毛将焉附”,为了创建Type这个“毛”,得先把Assembly,Module这些“皮”依次构造出来:

using System; using System.Reflection; using System.Reflection.Emit; public class TypeCreator {  private Type targetType;  /// <summary>  /// 构造函数  /// </summary>  /// <param name="targetType">被实现或者继承的类型</param>  public TypeCreator(Type targetType)  {   this.targetType = targetType;  }  public Type build()  {   //获取当前AppDomain   AppDomain currentAppDomain = AppDomain.CurrentDomain;   //System.Reflection.AssemblyName 是用来表示一个Assembly的完整名称的   AssemblyName assyName = new AssemblyName();   //为要创建的Assembly定义一个名称(这里忽略版本号,Culture等信息)   assyName.Name = "MyAssyFor_" + targetType.Name;   //获取AssemblyBuilder   //AssemblyBuilderAccess有Run,Save,RunAndSave三个取值   AssemblyBuilder assyBuilder = currentAppDomain.DefineDynamicAssembly(assyName,AssemblyBuilderAccess.Run);   //获取ModuleBuilder,提供String参数作为Module名称,随便设一个   ModuleBuilder modBuilder = assyBuilder.DefineDynamicModule("MyModFor_"+targetType.Name);   //新类型的名称:随便定一个   String newTypeName = "Imp_"+targetType.Name;   //新类型的属性:要创建的是Class,而非Interface,Abstract Class等,而且是Public的   TypeAttributes newTypeAttribute = TypeAttributes.Class | TypeAttributes.Public;   //声明要创建的新类型的父类型   Type newTypeParent;   //声明要创建的新类型要实现的接口   Type[] newTypeInterfaces;   //对于基类型是否为接口,作不同处理   if(targetType.IsInterface)   {    newTypeParent = null;    newTypeInterfaces = new Type[]{targetType};   }   else   {    newTypeParent = targetType;    newTypeInterfaces = new Type[0];   }   //得到类型生成器   TypeBuilder

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号