java_基础——用代码编译.java文件+加载class文件

  【本文介绍】  

  本文不是深入理解和使用java编译器,只是在代码里编译.java文件的helloWorld。这种技术还是蛮有意思的,说不定在将来的某些只能化项目会运用到!^_^

  【简单编译的流程】

  

  【java代码】

 1 package com.zjm.www.test;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.tools.JavaCompiler;
 6 import javax.tools.JavaCompiler.CompilationTask;
 7 import javax.tools.StandardJavaFileManager;
 8 import javax.tools.ToolProvider;
 9 
10 public class Test {
11 
12     public static void main(String[] args) {
13         
14           // 获取.java文件路径
15           String fileName = System.getProperty("user.dir")+
16             "\\src\\com\\zjm\\www\\test\\TankTimeProxy.java";
17           
18           /**
19            * ToolProvider类:该类是为查找工具提供者提供方法,例如,编译器的提供者。)
20            * getSystemJavaCompiler:获取此平台提供的 Java™ 编程语言编译器。
21            */
22           JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
23          
24           /**
25             * getStandardFileManager: 为此工具获取一个标准文件管理器实现的新实例。
26             * 参数:
27             *    diagnosticListener - 用于非致命诊断信息的诊断侦听器;如果为 null,则使用编译器的默认方法来报告诊断信息
28             *    locale - 格式化诊断信息时要应用的语言环境;如果为 null,则使用默认语言环境。
29             *    charset - 用于解码字节的字符集;如果为 null,则使用平台默认的字符集 
30             * 返回:
31             *    标准文件管理器
32             *
33            */
34           StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null,null,null);
35          
36           /**
37                * getJavaFileObjects:获取表示给定文件的文件对象。
38                * 参数:
39             *    files - 文件数组 
40             * 返回:
41             *    文件对象列表
42            */
43           Iterable units = fileMgr.getJavaFileObjects(fileName);
44          
45           /**
46                * getTask:使用给定组件和参数创建编译任务的 future
47                * 参数:
48             *    out - 用于来自编译器的其他输出的 Writer;如果为 null,则使用 System.err
49             *    fileManager - 文件管理器;如果为 null,则使用编译器的标准文件管理器
50             *    diagnosticListener - 诊断侦听器;如果为 null,则使用编译器的默认方法报告诊断信息
51             *    options - 编译器选项;null 表示没有选项
52             *    classes - 类名称(用于注释处理),null 表示没有类名称
53             *    compilationUnits - 要编译的编译单元;null 表示没有编译单元 
54             * 返回:
55             *    表示编译的对象
56            */
57           CompilationTask t = compiler.getTask(null,null,null,null,null,units);//编译任务
58          
59           //  开始编译
60           t.call();
61          
62           //  关闭“java编译器”
63           try {
64             fileMgr.close();
65         } catch (IOException e) {
66             e.printStackTrace();
67         }
68     }
69 }
View Code

 

  【其中的TankTimeProxy类】

1 package com.zjm.www.test;
2 
3 public class TankTimeProxy {
4 
5     public TankTimeProxy(){
6         System.out.println("hello TankTimeProxy");
7     }
8 }
View Code

 

  

  注:默认编译后的class文件与该java文件在同一个文件夹下。

 

  【加载class文件】

 

 1 package com.zjm.www.test;
 2 
 3 import java.net.URL;
 4 import java.net.URLClassLoader;
 5 
 6 public class Test2 {
 7 
 8     public static void main(String[] args) throws Exception {
 9           //1 去那个路劲下找这个类,默认是bin下面的classpath,因为自动编译后的class文件默认放在那里
10           URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src/")};
11          
12           //2 去urls里面去找class
13           URLClassLoader ul = new URLClassLoader(urls);
14          
15           //3 load哪个类,写全类名。
16           Class c = ul.loadClass("com.zjm.www.test.TankTimeProxy");
17          
18           // 打印:hello TankTimeProxy 即代表成功
19           Object o = c.newInstance();
20     }
21 }
View Code

 

   为了测试,我们在TankTimeProxy的构造方法中打印 "hello TankTimeProxy" ,如果加载类成功,那么当我们使用 newInstance() 方法时,该类的构造器将会被调用,从而打印"hello TankTimeProxy" , 实际中,确实打印出 "hello TankTimeProxy"。

 

posted @ 2014-08-04 11:59  小M的博客  阅读(1261)  评论(0编辑  收藏  举报