Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在用户提交的代码中调用静态方法的更好方法?_Java_Reflection - Fatal编程技术网

Java 在用户提交的代码中调用静态方法的更好方法?

Java 在用户提交的代码中调用静态方法的更好方法?,java,reflection,Java,Reflection,我有一个很大的数据集。我正在创建一个系统,允许用户提交java源文件,然后应用到数据集。更具体地说,每个提交的java源文件必须包含一个具有特定名称的静态方法,比如toBeInvoked。toBeInvoked将以数据集的一行作为数组参数。我想在数据集中的每一行上调用每个提交的源文件的toBeInvoked方法。我还需要实施安全措施,使被入侵的人无法执行I/O、无法呼叫出口等 目前,我的实现是这样的:我有一个java源文件的名称列表。对于每个文件,我创建一个自定义安全类加载器的实例,该实例由我编

我有一个很大的数据集。我正在创建一个系统,允许用户提交java源文件,然后应用到数据集。更具体地说,每个提交的java源文件必须包含一个具有特定名称的静态方法,比如toBeInvoked。toBeInvoked将以数据集的一行作为数组参数。我想在数据集中的每一行上调用每个提交的源文件的toBeInvoked方法。我还需要实施安全措施,使被入侵的人无法执行I/O、无法呼叫出口等

目前,我的实现是这样的:我有一个java源文件的名称列表。对于每个文件,我创建一个自定义安全类加载器的实例,该实例由我编写,它编译源文件并返回已编译的类。我使用反射提取静态方法toBeInvoked,例如method=c.getMethodtoBeInvoked,double[].class。然后,我迭代数据集的行,并在每一行上调用该方法

我的方法至少有两个问题:

它看起来慢得令人痛苦我听说反射往往很慢 代码比我想象的要复杂
有没有更好的方法来完成我想做的事情?

假设您的toBeInvoked可以在接口中定义,而不是应该是静态的!,您可以加载该类并将其强制转换到接口:

Class<? extends YourInterface> c = Class.forName("name", true, classLoader).asSubclass(YourInterface.class);
YourInterface i = c.newInstance();
之后直接调用toBeInvoked


还可以查看java.util.ServiceLoader,如果您有多个源文件,它可能有助于找到要加载的正确类。

我个人会使用接口。这将允许您拥有多个具有自己状态的实例,这些实例对多线程非常有用,但更重要的是,您可以使用一个接口,首先定义必须实现哪些方法,还可以调用这些方法


反射很慢,但这仅与其他选项(如直接方法调用)相关。如果要扫描大型数据集,则必须从主存中提取数据的成本可能会高得多。

考虑到您自己设置的限制,没有明显更好的方法

值得一提的是,将源文件编译成类文件并加载它们,这会让速度非常慢。这比使用反射调用方法要慢很多数量级

使用公共接口而不是静态方法不会对速度产生可测量的影响,复杂性的降低相对较小


如果您真的想简化并加速它,请更改您的体系结构,以便将代码作为包含所有编译类的JAR文件提供。

我建议您按照以下步骤解决问题

要检查该方法是否包含任何不需要的代码,您需要有一个检查脚本,该脚本可以在上载时执行这些检查。 创建一个接口,该接口的方法被调用,而不是静态方法。 所有上传的类都必须实现这个接口,并在这个方法中添加逻辑。 您可以让自定义类加载器扫描特定文件夹中添加的新类,并相应地加载它们。 上载并成功验证文件后,可以编译类文件并将其复制到类加载器扫描的文件夹中。 处理器类可以查找新文件,然后在需要时对加载的类调用toBeInvoked方法。
希望这有帮助。请注意,我使用了类似的机制在开发的workflow Engine tool中动态加载工作流步骤类。

这里最昂贵的事情很可能不是反射调用,除非它确实经常被调用,而是编译!你是怎么编的?使用内置的JavaCompiler类,或者通过一些外部Runtime.exec调用?`在任何情况下,除了编译之外,插件的功能通常都可以通过实现,尽管还不完全清楚这是否适用于您的情况。