- 浏览: 274887 次
- 性别:
- 来自: 山东
最新评论
-
xchz:
没想到做的这么完善
状态模式-实现屏幕截取程序 -
songwangchu:
不错啊。哈哈哈
Reactor模式,或者叫反应器模式 -
yuanliangding:
很简洁易懂。怎么没有系列文章
Reactor模式,或者叫反应器模式 -
过冷水:
讲的不错
Reactor模式,或者叫反应器模式 -
Hero_z:
讲的非常通俗易懂,108个赞!!!
Reactor模式,或者叫反应器模式
一般情况下对java源文件的编译均是在代码完成后使用javac编译的,不管是使用IDE还是直接使用命令行。这里要说的情况是比较特别的,就是在代码内动态的编译一些代码。比如你想通过在某个目录下通过放置一些源代码的方式来实现对程序功能的动态扩展,那么你的程序就需要具有一种对源代码的编译、加载、运行的能力,可能就需要本文介绍的3种方法。
在java程序中调用javac命令可以通过调用Runtime类的exec或是ProcessBuilder类的start方法来完成,这两个类的功能基本相同,用法也比较相似,这里的例子我们就用ProcessBuilder来演示。如果是JDK1.5之前的版本请使用Runtime类完成相同的功能。
开始之前先来点准备工作,将下面的类放到 c:\mytest\src\ 目录下,这个类我们不会在IDE中编译,而是由我们程序完成其编译。保存时使用UTF-8格式。可以直接在附件中下载这个类。
准备工作完成,下面就看一下我们程序的代码,这里只列出主要代码
LoaderClassByDir类的代码会保含在后面的上传的文件中,因为这里主要介绍完成程序中对java源文件的编译,对于类的加载和运行不多做描述,可以参考LoaderClassByDir类中的简单实现。
方法2:使用Sun的tools.jar包时的com.sun.tools.javac.Main类完成对代码的编译。
注意这个类的是在tools.jar包里,tools.jar不是标准的Java库,在使用时必须要设置这个jar的路径,使用IDE时需要显示的引入到编译路径中,不然会找不到。我们使用此类改写上面的编译类如下:
使用这个类后,同样的功能代码变得更加简洁。
从上面可以看到方法2的缺点就是tools.jar需要我们自行导入。而在Java SE6中为我们提供了标准的包来操作Java编译器,这就是javax.tools包。使用这个包,我们可以不用将jar文件路径添加到classpath中了。 使用这个类的方法和上面的类很相似,我只需要将
替换成:
就可以完成相应的编译功能,这里简介一下run的使用方法:
注意:使用上传文件中的代码做测试时,为避免上次编译的影响记得手动删除C:\mytest\bin下的类文件
这里的参数设置和javac的参数基本上是一致的,如果想指定classpath,可以指定-cp参数,使用样例如下:
如上就可以将sun的tools.jar引入到编译路径中
方法1:通过调用本机的javac命令来编译。
在java程序中调用javac命令可以通过调用Runtime类的exec或是ProcessBuilder类的start方法来完成,这两个类的功能基本相同,用法也比较相似,这里的例子我们就用ProcessBuilder来演示。如果是JDK1.5之前的版本请使用Runtime类完成相同的功能。
开始之前先来点准备工作,将下面的类放到 c:\mytest\src\ 目录下,这个类我们不会在IDE中编译,而是由我们程序完成其编译。保存时使用UTF-8格式。可以直接在附件中下载这个类。
public class HelloWorld { public void sayHello(String in) { System.out.println("动态编译成功"); System.out.println("使用编译方式:" + in); } }
准备工作完成,下面就看一下我们程序的代码,这里只列出主要代码
public class JavacCompile { private static String filePath = "c:\\mytest\\src\\HelloWorld.java"; private static String binDir = "c:\\mytest\\bin"; public static void main(String[] args) { File binOutDir = new File(binDir); if (!binOutDir.exists()) { binOutDir.mkdirs(); } // 设置javac的编译参数,使用-encoding指定编码方式,-d并指定编译生成class文件目录 ProcessBuilder pb = new ProcessBuilder("javac","-encoding", "UTF-8","-d", binDir, filePath); try { // 开始调用javac命令编译 final Process proc = pb.start(); // 处理进程的输出,避免挂死 new Thread(new Runnable() { public void run() { processStream(proc.getInputStream()); processStream(proc.getErrorStream()); } }).start(); // 等待编译完成 proc.waitFor(); // 加载编译好的类,并调用相应的方法 new LoaderClassByDir(binDir).execSayHello("javac"); } catch (Exception ex) { Logger.getLogger(JavacCompile.class.getName()).log(Level.SEVERE, null, ex); } } private static void processStream(InputStream stderr) { ... } }
LoaderClassByDir类的代码会保含在后面的上传的文件中,因为这里主要介绍完成程序中对java源文件的编译,对于类的加载和运行不多做描述,可以参考LoaderClassByDir类中的简单实现。
方法2:使用Sun的tools.jar包时的com.sun.tools.javac.Main类完成对代码的编译。
注意这个类的是在tools.jar包里,tools.jar不是标准的Java库,在使用时必须要设置这个jar的路径,使用IDE时需要显示的引入到编译路径中,不然会找不到。我们使用此类改写上面的编译类如下:
public class JavacCompile { private static String filePath = "c:\\mytest\\src\\HelloWorld.java"; private static String binDir = "c:\\mytest\\bin"; public static void main(String[] args) { File binOutDir = new File(binDir); if (!binOutDir.exists()) { binOutDir.mkdirs(); } // 将编译参数通过数组传递到编译方法中,该函数的方法和javac的参数完成一致 Main.compile(new String[]{"-encoding", "UTF-8","-d", binDir, filePath}); try { // 加载编译好的类,并调用相应的方法 new LoaderClassByDir(binDir).execSayHello("sun tools"); } catch (Exception ex) { Logger.getLogger(JavacCompile.class.getName()).log(Level.SEVERE, null, ex); } } }
使用这个类后,同样的功能代码变得更加简洁。
方法3:使用javax.tools包
从上面可以看到方法2的缺点就是tools.jar需要我们自行导入。而在Java SE6中为我们提供了标准的包来操作Java编译器,这就是javax.tools包。使用这个包,我们可以不用将jar文件路径添加到classpath中了。 使用这个类的方法和上面的类很相似,我只需要将
Main.compile(new String[]{"-encoding", "UTF-8","-d", binDir, filePath});
替换成:
// 将编译参数通过数组传递到编译方法中,该函数的方法和javac的参数完成一致 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); compiler.run(null, null, null, "-encoding", "UTF-8","-d", binDir, filePath);
就可以完成相应的编译功能,这里简介一下run的使用方法:
引用
我们可以通过ToolProvider类的静态方法getSystemJavaCompiler来得到一个JavaCompiler接口的实例。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaCompiler中最核心的方法是run。通过这个方法可以编译java源程序。这个方法有3个固定参数和1个可变参数(可变参数是从 Jave SE5开始提供的一个新的参数类型,用type… argu表示)。前3个参数分别用来为java编译器提供参数、得到Java编译器的输出信息以及接收编译器的错误信息,后面的可变参数可以传入一个或多个Java源程序文件。如果run编译成功,返回0。
int run(InputStream in, OutputStream out, OutputStream err, String... arguments)
如果前3个参数传入的是null,那么run方法将以标准的输入、输出代替,即System.in、System.out和System.err。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaCompiler中最核心的方法是run。通过这个方法可以编译java源程序。这个方法有3个固定参数和1个可变参数(可变参数是从 Jave SE5开始提供的一个新的参数类型,用type… argu表示)。前3个参数分别用来为java编译器提供参数、得到Java编译器的输出信息以及接收编译器的错误信息,后面的可变参数可以传入一个或多个Java源程序文件。如果run编译成功,返回0。
int run(InputStream in, OutputStream out, OutputStream err, String... arguments)
如果前3个参数传入的是null,那么run方法将以标准的输入、输出代替,即System.in、System.out和System.err。
注意:使用上传文件中的代码做测试时,为避免上次编译的影响记得手动删除C:\mytest\bin下的类文件
- HelloWorld.zip (349 Bytes)
- 描述: 需动态编译的源文件
- 下载次数: 108
- src.zip (3.7 KB)
- 描述: 程序源代码
- 下载次数: 140
评论
2 楼
daimojingdeyu
2009-10-14
wubo19842008 写道
用javax.tool包编译时,如果源文件依赖外部jar包,如何设置classpath啊?
这里的参数设置和javac的参数基本上是一致的,如果想指定classpath,可以指定-cp参数,使用样例如下:
int result = compiler.run(null, null, null, "-encoding", "UTF-8", "-cp", "D:/Program Files/Java/jdk1.6.0_14/lib/tools.jar", "-d", binDir, filePath);
如上就可以将sun的tools.jar引入到编译路径中
1 楼
wubo19842008
2009-10-14
用javax.tool包编译时,如果源文件依赖外部jar包,如何设置classpath啊?
发表评论
-
转:idea点用C盘空间解决办法
2015-03-30 17:02 1566原文:http://my.oschina.net/ulyn ... -
转:Java安全模型
2015-02-26 13:50 843原文地址:http://www.ibm.com/develo ... -
序列化对象大小计算
2013-01-21 16:45 0import java.io.ByteArrayOutput ... -
wait死了,今天真是郁闷
2012-09-13 22:21 1048wait should always be in syn ... -
获取所有淘金币全额兑换商品
2012-08-08 16:36 1784找淘金币全额兑换的商品是不是很麻烦,点来点去每个类目找一下,等 ... -
gc 日志格式
2011-03-04 14:58 0Here's an example GC log file w ... -
使用Oauth向新浪微博发消息
2011-02-13 00:16 4797最近看了一下新浪围脖 ... -
classloader
2011-02-12 16:57 0/** * classloader single * ... -
mail
2011-02-12 16:28 0package org.mail.core; impor ... -
Mina原理草图及注释
2011-01-18 23:00 5969今天先画一个草图备忘,明天再注释一下。 上图 ... -
Reactor模式,或者叫反应器模式
2010-11-29 22:29 69529Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应 ... -
eclipse“随变”,随机变换eclipse启动界面
2010-06-02 20:17 4383对eclipse的启动界面审美疲劳了,手贱,想换掉它,趁老婆不 ... -
java编译时生成调试信息选项详解(javac -g)
2010-05-30 02:31 6326引子 先说一下为什么 ... -
文件Copy,什么方式才最快呀~~
2010-05-17 23:31 1557闲逛CSDN,发现有人找文件Copy的方法,顺手解答了一下,有 ... -
Eclipse调试常用技巧
2010-04-06 01:43 25855本文写给那些像几年前的我一样刚刚走出校门,及一些未使用过这些高 ... -
log4j真的比JDK logger快吗?
2009-09-20 23:58 4289这里不想比较这两个日 ... -
String.format函数使用方法介绍
2009-08-09 10:52 2077转自:http://blog.csdn.net/andycpp ... -
Java读带有BOM的UTF-8文件乱码原因及解决方法
2009-05-28 01:31 20346最近在处理文件时发现了同样类型的文件使用的编码可能是不同的。所 ... -
Java正则与栈溢出
2009-05-13 00:09 4927使用RegexBuddy测试正确的 ... -
Java 正则表达式处理选项及SQL注释删除
2009-05-09 23:58 5992常 量 等效的嵌入标志表达式 ...
相关推荐
### 在程序中实现对Java源文件编译的三种方法 #### 方法一:通过调用本机的`javac`命令来编译 本方法适用于在程序内部动态编译Java源文件的情形,例如需要通过放置一些源代码的方式实现对程序功能的动态扩展。此...
### 在程序中实现对Java源文件编译的三种方法 #### 方法一:通过调用本机的`javac`命令来编译 本方法适用于在Java程序内部动态编译源代码的情形,例如需要通过放置一些源代码来实现程序功能的动态扩展。此方法通过...
Java动态编译指的是在程序运行时将Java源代码编译为字节码并加载到Java虚拟机(JVM)中的过程。这种技术在许多场景下非常有用,例如在开发环境中进行快速迭代、AOP(面向切面编程)或运行时代码生成等。Java的`javax...
这篇博客“Java类动态加载(一)——java源文件动态编译为class文件”可能主要探讨了如何在运行时将Java源代码(.java)编译成对应的字节码文件(.class),并将其加载到Java虚拟机(JVM)中。以下是对这个主题的详细解析...
Java反编译是一种技术,它允许开发者从已编译的.class文件中恢复原始的.java源代码。这在一些情况下非常有用,例如分析第三方库的内部实现、研究代码逻辑或者在丢失源代码时恢复源码。Java编译器将源代码转换成字节...
Java反编译是Java开发中一个重要的辅助工具,它能够帮助开发者查看已编译的`.class`文件中的源代码,即使原始的`.java`源文件已经丢失或未被提供。这个过程对于理解类库的工作原理、逆向工程、调试、学习或者分析...
Java编译器将Java源文件编译成Java字节码文件,扩展名为.class。编译器可以使用javac命令来编译Java源文件。在命令窗口中,使用javac命令编译指定目录下的Java源文件。 例如,在上面的示例程序中,使用javac命令...
通过java的ToolProvider创建JavaCompile,用来执行class源文件 * 4.创建DiagnosticCollector用来执行获取执行失败的错误结果 * 5.添加动态执行的编译环境 options 是个集合,添加内容,字符集,classpath等 * 6....
在我们的例子中,我们可以使用`JavaCompiler`来编译指定的Java源文件。以下是一个简单的示例: ```java import javax.tools.*; import java.io.*; import java.util.*; public class BuildRmi { public static ...
泛型是Java中用于增强类型安全性的特性,允许在编译时检查类型。通过实例,你可以学习如何定义和使用泛型类、接口和方法。 10. **反射**: 反射机制允许程序在运行时检查类的信息,如类名、方法名和属性。这在...
在Java中,多态分为编译时多态(方法重载)和运行时多态(方法重写)。运行时多态是通过接口和继承实现的。 5. **抽象**:抽象是将共同特征提取出来形成抽象类或接口的过程。抽象类不能实例化,但可以作为其他类的...
描述中强调了这个软件的功能,即把编译后的class文件转换回Java源文件。这在某些场景下非常有价值,例如,当你遇到一个没有源码但只有字节码的库,或者想查看某个二进制组件的内部实现时。 在Java反编译领域,有...
在Java开发环境中,.class文件是由Java编译器(javac)将.java源代码编译得到的,它们包含了Java程序的机器码,但并不直接包含源代码。当需要查看这些二进制文件中的方法和变量定义,或者无法获得源代码时,反编译...
在给定的代码片段中,我们可以看到一个名为`BatchCompiler`的Java类,该类旨在实现Java源文件的批量编译。以下是对代码中关键部分的分析: 1. **数据结构选择**:代码使用了`LinkedList<String>`来存储待处理的目录...
接口在Java中用于定义一种合同,规定了实现该接口的类必须提供哪些方法。在源文件中,我们可能会看到如`ReservationInterface.java`这样的接口定义文件,它定义了预定服务需要实现的方法。 5. **异常(Exception)...
虽然手动编译和运行Java程序是了解其工作原理的重要途径,但在实际开发中,我们通常使用集成开发环境(IDE),如Eclipse、IntelliJ IDEA等,它们提供了自动编译、调试和运行的功能,极大地提高了开发效率。...
Java动态编译是一种技术,允许程序在运行时将源代码转换为字节码并加载到JVM(Java虚拟机)中。这种能力使得Java应用程序能够根据需要编译和执行新的代码,增强了软件的灵活性和可扩展性。在给定的场景中,用户通过...
Java反编译是Java开发过程中一个重要的辅助工具,主要用于查看已编译的`.class`文件或`.jar`包中的源代码。在某些情况下,我们可能需要查看这些源代码,例如学习某个开源库的工作原理,或者排查Java应用的问题,而...