我想导入一个我已经写在外部文件夹中的类,例如:我的类Example.java
位于c:\class\Example.java
我的脚本中,比如使用
var importedClass = new JavaImporter("c:\\class\\Example.java");
或者
importClass("c:\\class\\Example.java");
这是在 ScriptEngine rhino 的脚本中
我该怎么做???
我了解您想要:
javax.tools包提供了一种编译代码的机制,但如果您没有在 JDK 中运行,ToolProvider.getSystemJavaCompiler()将返回null
,您将不得不依赖其他一些编译机制(调用外部编译器;嵌入Eclipse 编译器等)。
Java 字节码(.class
二进制文件)可以在运行时通过ClassLoader 加载。
为了使加载的类对您的脚本引擎可见,您需要通过ScriptEngineManager(ClassLoader)构造函数提供它们。
编辑:根据要求
public class HelloWorld {
public void say() {
System.out.println("Hello, World!");
}
}
HelloWorld.class
这个脚本只是调用 Java 反射 API 来从目录加载和实例化一个类C:\foo\bin
:
function classImport() {
var location = new java.net.URL('file:/C:/foo/bin/');
var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, 1);
urlArray[0] = location;
var classLoader = new java.net.URLClassLoader(urlArray);
return classLoader.loadClass("HelloWorld");
}
var myClass = classImport();
for(var i=0; i<10; i++) {
myClass.getConstructor(null).newInstance(null).say();
}
我敢肯定,还有更优雅的方法可以做到这一点。
我会质疑为什么要这样做。
此处列出的解决方案将起作用。问题将是:
如果我对您的理解正确,您实际上要做的是加载 Java 类,以便您可以(可能)创建实例等。术语是动态加载而不是导入。
Java 允许您*.class
使用该ClassLoader.loadClass(String)
方法动态加载字节码文件 ( )。关于这个主题有很多资源;例如,JNDI 教程中的“类加载”页面。准备好花一些时间了解这个话题。特别是,由于您尝试加载不在应用程序正常类路径上的类,因此您需要创建一个新的类加载器来执行此操作。java.lang.ClassLoader
该类的 Javadocs 在这里。
Java源代码不能直接加载,必须先用Java编译器编译。如果您使用的是现代 JDK 安装,则可以在运行时调用 Java 编译器。但是 JRE 安装不包括 Java 编译器。如果您的平台在运行时有可用的 Java 编译器,您可以通过类的getSystemJavaCompiler()
静态方法访问它ToolProvider
。再一次,从正在运行的 Java 应用程序中调用 Java 编译器很复杂。