执行外部.class文件?

时间:2012-12-05 00:52:51

标签: java reflection external execute

所以,我有一个.class文件及其绝对路径,我需要知道如何从Java内部执行.class文件。如果我能够从中获得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?*/

1 个答案:

答案 0 :(得分: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>