首页 / JAVA / Java动态编译和动态加载详解
Java动态编译和动态加载详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java动态编译和动态加载详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3356字,纯文字阅读大概需要5分钟。
内容图文
![Java动态编译和动态加载详解](/upload/InfoBanner/zyjiaocheng/852/42a2a13343e64e0aa66532e3cf420553.jpg)
一.动态编译
在某些情况下,我们需要动态生成java代码,通过动态编译,然后执行代码。JAVA API提供了相应的工具(JavaCompiler)来实现动态编译。
//获取JavaCompiler JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//获取java文件管理类 StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
//获取java文件对象迭代器 Iterable<? extends JavaFileObject> it = manager.getJavaFileObjects(files);
//设置编译参数 ArrayList<String> ops = new ArrayList<String>(); ops.add("-Xlint:unchecked");
//可以指定源文件或目标文件的JDK版本 ops.add("-source")/ops.add("-target");; ops.add("1.5");
//获取编译任务:第一个null,用于输出错误的流,默认是System.err;第二个null,diagnosticListener: 编译器的默认行为 ;第三个null,classes,参与编译的class,为null时表示全部
//JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, ops, null, it);
//执行编译任务 task.call();
动态编译几个关键类
类名 |
作用 |
创建方式 |
JavaCompiler |
动态编译的入口,也是基础类 |
ToolProvider.getSystemJavaCompiler() |
StandardJavaFileManager |
java文件管理类 |
compiler.getStandardFileManager |
Iterable |
文件对象迭代器 |
manager.getJavaFileObjects(files) |
ArrayList<String> |
编译参数 |
new ArrayList<String>() |
踩坑记
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 这句代码在IDEA中运行正常,然后打成jar包在桌面双击运行时得到的是null
问题解决:
查看ToolProvider源码可知,是因为找不到tools.jar---》将tools.jar复制到jre/lib下
二.动态加载
JAVA中的类加载:双亲委派模式
URL url = new URL("file:" + CLASS_PATH);
ClassLoader classLoader = new URLClassLoader(new URL[]{url});
Class<?> cls = classLoader.loadClass(name);
Method method = cls.getDeclaredMethod(String methodName)
Object obj = cls.newInstance();
Object result = method.invoke(Object obj, Object[] params);
class.forName()和classLoader区别:
//Class.forName(String className) 这是1.8的源码
public static Class<?> forName(String className) throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
//注意第二个参数,是指Class被loading后是不是必须被初始化。 不初始化就是不执行static的代码即静态代码 class.forName()前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
而classLoader只干一件事情,就是将.class文件加载到jvm中。
扩展:TOMCAT中的类加载架构
1、JAVA_HOME:设置为JDK的安装目录,如D:\java\jdk1.8。一些依赖JAVA的软件通过该环境变量来获得JDK的安装目录,如大家都知道的Eclipse、Tomcat等。
2、PATH:在已有值最后加上 ;%JAVA_HOME%\bin ,其中;是分隔符,用于分开每个目录,其中%JAVA_HOME%则是引用上面的JAVA_HOME环境变量的值,可以直接用JDK的安装目录代替,下面的CLASSPATH类似。执行路径(也就是PATH环境变量的值)是只操作系统搜索本地可执行文件的目录列表,在shell中执行命令时,它会在执行路径中查找所对应的程序。所以在PATH中加入了%JAVA_HOME%\bin目录后,在shell中就可以执行javac或者java命令。
3、CLASSPATH:设置值为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; 注意其中的标点符号,其中第一个点“.”表示当前目录,而分号“;”则是分隔符。 这个CLASSPATH为JVM加载类的目录,比如HelloWorld.java中有import其他类,用javac编译时它会在CLASSPATH中去找你所import的类,如果找不到则出现编译错误。 另外在使用java时使用-classpath 参数可以指定要加载类的目录,比如命令行执行:C:/UsersJakey>java -classpath D:\temp HelloWorld ,这样就可以当命令行在C盘时执行D盘目录中的JAVA类。
内容总结
以上是互联网集市为您收集整理的Java动态编译和动态加载详解全部内容,希望文章能够帮你解决Java动态编译和动态加载详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。