1

所以,我有一个.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?*/
4

1 回答 1

4

诀窍是访问 ClassLoader 的 defineClass 方法。假设您想动态加载实现已知接口的随机类文件(如果您不知道接口,您将使用反射 api 来查找和调用方法)。

package com.example.fileclassloader;

public interface Dynamo {
    public Integer beDynamic(String s);
}

某处是实现该接口的编译类。它可能看起来像:

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();
  }
}

现在要使用它,我们需要扩展一个类加载器,以便我们可以访问 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();
        }
}

现在我们需要使用动态加载的类实例。我们将它转​​换为我们期望它符合的接口,并像使用该接口的任何其他实例一样使用它:

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));

    }

}

为了更好地衡量,这里是构建它的 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>
于 2012-12-05T04:55:01.520 回答