• java笔记十一:动态编译


      JDK6.0推出了动态编译的新功能,能够在程序中动态的写一个类,再对之进行编译。编译成class文件后就可以通过类加载方式把动态编译的类加载到内存中。当然也能通过RunTime类调用javac命令来动态编译。

      动态编译类的主要步骤:

      ①、写一个字符串,这个字符串就是要编译的类的全部内容。

      ②、通过输出流,把该字符串的内容写到工程下面指定的包中。

      ③、对创建的java文件进行编译。

        动态编译涉及的类有JavaCompiler、StandardJavaFileManager,具体如何编译看下面的例子。

      ④、把编译后的字节码加载到内存,然后对其进行操作。

     1 package com.compiler;
     2 import java.io.*;
     3 import java.lang.reflect.InvocationTargetException;
     4 import java.net.URI;
     5 import java.net.URL;
     6 import java.net.URLClassLoader;
     7 import java.util.Arrays;
     8 
     9 import javax.tools.JavaCompiler;
    10 import javax.tools.SimpleJavaFileObject;
    11 import javax.tools.StandardJavaFileManager;
    12 import javax.tools.JavaFileObject; 
    13 import javax.tools.ToolProvider;
    14 
    15 public class CompilerAPITester {
    16     private static String JAVA_SOURCE_FILE = "DynamicObject.java";
    17     private static String JAVA_CLASS_FILE = "DynamicObject.class";
    18     private static String JAVA_CLASS_NAME = "DynamicObject";
    19 
    20     public static void main(String[] args) throws IOException, InterruptedException {
    21         //创建java文件
    22         String tr = "\r\n";
    23         String source = "package com.compiler;" + tr +
    24                 "public class "+JAVA_CLASS_NAME+ "{ " + tr +
    25                 "    public static void main(String[] args) {" + tr +
    26                 "        System.out.println(\"Hello World!\");" + tr +
    27                 "    } " + tr +
    28                 "}";
    29         String fileName = System.getProperty("user.dir")+"\\src\\com\\compiler\\"+JAVA_SOURCE_FILE;
    30         FileWriter fw = new FileWriter(fileName); //字符输出流
    31         PrintWriter pw = new PrintWriter(fw);     //将字节输出流转为PrintWriter
    32         pw.write(source);
    33         pw.close();
    34         //编译java文件
    35         JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    36         StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    37         Iterable sourcefiles = fileManager.getJavaFileObjects(fileName);
    38         //指定编译文件存放位置,如果不指定的话,编译的文件会和java源文件在一个文件夹中
    39          //这样的话加载类的时候会报java.lang.ClassNotFoundException
    40         Iterable<String> options = Arrays.asList("-d", System.getProperty("user.dir")+"\\WebRoot\\WEB-INF\\classes");
    41         compiler.getTask(null, fileManager, null, options, null, sourcefiles).call();
    42         fileManager.close();
    43         //方法二:
    44         /*Runtime runtime = Runtime.getRuntime();
    45         runtime.exec("javac -d "+ System.getProperty("user.dir")+"\\WebRoot\\WEB-INF\\classes " +fileName);
    46         Thread.sleep(1000);*/ //因为这种方法时调用一个线程取编译,所以要让主线程睡一会儿,否则还没编译完主线程就加载类了,会导致报类无法找到的异常
    47         try {
    48             //加载类到内存
    49             //方法一:
    50             //Class c = Class.forName("com.compiler."+JAVA_CLASS_NAME);
    51             //方法二:
    52             //Class c = ClassLoader.getSystemClassLoader().loadClass("com.compiler."+JAVA_CLASS_NAME);
    53             //方法三:
    54             URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src")};
    55             URLClassLoader loader = new URLClassLoader(urls);
    56             Class c = loader.loadClass("com.compiler."+JAVA_CLASS_NAME);
    57             //调用加载类的main方法
    58             c.getMethod("main",String[].class).invoke(null, (Object)new String[]{"a"});
    59         } catch (Exception e) {
    60             // TODO Auto-generated catch block
    61             e.printStackTrace();
    62         }
    63     }
    64 
    65 } 
  • 相关阅读:
    oracle的安装与plsql的环境配置
    Working with MSDTC
    soapui-java.lang.Exception Failed to load url
    Oracle 一个owner访问另一个owner的table,不加owner
    Call API relation to TLS 1.2
    Call API HTTP header Authorization: Basic
    VS2008 .csproj cannot be opened.The project type is not supported by this installat
    The changes couldn't be completed.Please reboot your computer and try again.
    Create DB Table View Procedure
    DB Change
  • 原文地址:https://www.cnblogs.com/liuling/p/dynamicCompiler.html
Copyright © 2020-2023  润新知