Ste*_*ven 3 java reflection external execute
因此,我有一个.class文件及其绝对路径,我需要知道如何.class从 Java 内部执行该文件。Class如果我也能从中得到一样东西就好了。
我知道loadClass中的方法ClassLoader,但它需要文件的“二进制名称”。我不确定是否可以获得外部.class文件的二进制名称,但如果可以的话,那会很有用!但是,如果没有,是否有其他方法来执行或获取外部文件的实例.class?
/*For those of us who work better with examples..
Let's say I have a .class file located at C:/Users/USER/Desktop. So..*/
String absolutePath = "C:/Users/USER/Desktop/FILE.class";
/*Now, having that, how would I get an instance of that class, or,
at least, execute it?*/
Run Code Online (Sandbox Code Playgroud)
诀窍是访问 ClassLoader 的 DefineClass 方法。假设您想要动态加载一个实现已知接口的随机类文件(如果您不知道该接口,您将使用反射 api 来查找和调用方法)。
package com.example.fileclassloader;
public interface Dynamo {
public Integer beDynamic(String s);
}
Run Code Online (Sandbox Code Playgroud)
某个地方有一个实现该接口的编译类。它可能看起来像:
public class Sample implements com.example.fileclassloader.Dynamo {
public Integer beDynamic(String s) {
System.out.println(String.format("The value is: %s", s));
return s.length();
}
}
Run Code Online (Sandbox Code Playgroud)
现在要使用它,我们需要扩展一个类加载器,以便我们可以访问 DefineClass 方法。这个将只接受文件名,加载字节并创建实例:
package com.example.fileclassloader;
import java.io.File;
import java.io.IOException;
import java.security.SecureClassLoader;
public class MyDynamoClassLoader extends SecureClassLoader {
public Object createObjectFromFile(String fileName) throws
InstantiationException, IOException, IllegalAccessException {
File file = new File(fileName);
byte[] classBytes =
org.apache.commons.io.FileUtils.readFileToByteArray(file);
Class<?> clazz = defineClass(null, classBytes, 0, classBytes.length);
return clazz.newInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要使用动态加载的类实例。我们将其转换为我们期望它符合的接口,并像该接口的任何其他实例一样使用它:
package com.example.fileclassloader;
import java.io.FileNotFoundException;
import java.io.IOException;
public class App {
public static void main() throws FileNotFoundException, IOException,
InstantiationException, IllegalAccessException {
String fname = "target/classes/com/example/fileclassloader/Sample.class";
MyDynamoClassLoader loader = new MyDynamoClassLoader();
Dynamo dynamo = (Dynamo) loader.createObjectFromFile(fname);
Integer i = dynamo.beDynamic("Testing");
System.out.println(String.format("Dynamo (%s) returned %d", fname, i));
}
}
Run Code Online (Sandbox Code Playgroud)
为了更好地衡量,这里是用于构建它的 pom.xml 文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>fileclassloader</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2653 次 |
| 最近记录: |