Apache的BCEL庫,文檔很少,例子也很簡單。動態(tài)構(gòu)建類的工作,要求的只是并不是熟練使用BCEL類庫本身,而是要對java的class結(jié)構(gòu)了解。我對java的pcode也不熟悉,但是我曾經(jīng)做過大量的.NET的反編譯工作,兩者類似,所以我用BCEL也不覺得困難。

          我提供一個例子,這里例子是使用BCEL創(chuàng)建類的實例,而不是使用反射。

          如下:

          IFactory.java

          public interface IFactory {
              
          public Object newInstance();    
          }

          FileClassLoader.java
          import java.io.ByteArrayOutputStream;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.IOException;

          public class FileClassLoader extends ClassLoader {
              
          public FileClassLoader() {
                  super();
              }


              
          public FileClassLoader(ClassLoader parent) {
                  super(parent);
              }


              
          public Class getClass(String className, String filePath) {
                  FileInputStream fileInputStream 
          = null;
                  
          byte[] data = null;
                  
          try {
                      fileInputStream 
          = new FileInputStream(new File(filePath));

                      ByteArrayOutputStream byteArrayOutputStream 
          = new ByteArrayOutputStream();
                      
          int ch = 0;
                      
          while ((ch = fileInputStream.read()) != -1{
                          byteArrayOutputStream.write(ch);
                      }

                      data 
          = byteArrayOutputStream.toByteArray();
                      
          return defineClass(className, data, 0, data.length);
                  }
           catch (IOException e) {
                      e.printStackTrace();
                      
          throw new Error(e.getMessage(), e);
                  }

              }

          }

          buildFactory方法:
          public static IFactory buildFactory(String procductClassName)
                  throws Exception 
          {
              InstructionList il 
          = new InstructionList();
              String className 
          = "HelloWorld";
              ClassGen class_gen 
          = new ClassGen(className, "java.lang.Object",
                      
          "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null);
              ConstantPoolGen cons_pool 
          = class_gen.getConstantPool();
              class_gen.addInterface(IFactory.
          class.getName());

              InstructionFactory il_factory 
          = new InstructionFactory(class_gen);

              
          // 創(chuàng)建構(gòu)造函數(shù)
              {
                  String methodName 
          = "";

                  Type returnType 
          = Type.VOID;
                  Type[] arg_Types 
          = new Type[] {};
                  String[] arg_names 
          = new String[] {};
                  MethodGen method_gen 
          = new MethodGen(Constants.ACC_PUBLIC,
                          returnType, arg_Types, arg_names, methodName, className,
                          il, cons_pool);

                  
          // super();
                  il.append(InstructionFactory.createLoad(Type.OBJECT, 0));
                  il.append(il_factory.createInvoke(
          "java.lang.Object""",
                          Type.VOID, 
          new Type[0], Constants.INVOKESPECIAL));
                  il.append(InstructionFactory.createReturn(Type.VOID));

                  method_gen.setMaxStack();
                  class_gen.addMethod(method_gen.getMethod());
                  il.dispose(); 
          // Reuse instruction handles of list
              }


              
          {
                  String methodName 
          = "newInstance";
                  Type returnType 
          = Type.OBJECT;
                  Type[] arg_Types 
          = new Type[] {};
                  String[] arg_names 
          = new String[] {};
                  MethodGen method_gen 
          = new MethodGen(Constants.ACC_PUBLIC,
                          returnType, arg_Types, arg_names, methodName, className,
                          il, cons_pool);
                  il.append(il_factory.createNew(procductClassName));
                  il.append(InstructionConstants.DUP);
                  il.append(il_factory.createInvoke(procductClassName, 
          "",
                          Type.VOID, 
          new Type[0], Constants.INVOKESPECIAL));
                  il.append(InstructionFactory.createReturn(Type.OBJECT));
                  method_gen.setMaxStack();

                  class_gen.addMethod(method_gen.getMethod());
                  il.dispose(); 
          // Reuse instruction handles of list
              }


              
          // 保存到文件中
              JavaClass clazz = class_gen.getJavaClass();
              String path 
          = "e:\\temp\\" + className + ".class";
              class_gen.getJavaClass().dump(path);

              
          // 使用ClassLoader裝載class
              FileClassLoader classLoader = new FileClassLoader();
              Class factoryClass 
          = classLoader.getClass(className, path);
              Object newInst 
          = factoryClass.newInstance();

              
          return (IFactory) newInst;
          }

          測試用例:
          String className = "java.lang.Object";
          IFactory factory 
          = buildFactory(className);
          Object inst 
          = factory.newInstance();
          posted on 2005-04-14 23:59 溫少的日志 閱讀(8638) 評論(7)  編輯  收藏
          Comments

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
           
          主站蜘蛛池模板: 姚安县| 谷城县| 精河县| 吉林省| 普格县| 清苑县| 外汇| 鞍山市| 建平县| 东台市| 古浪县| 天峻县| 资源县| 赣榆县| 定日县| 邻水| 新绛县| 尼玛县| 平湖市| 靖边县| 潍坊市| 沂南县| 淮北市| 岫岩| 南部县| 平顺县| 崇仁县| 水城县| 资阳市| 基隆市| 南涧| 建湖县| 滁州市| 钟祥市| 竹山县| 和林格尔县| 牟定县| 云龙县| 胶南市| 高雄县| 凤山县|