Java:加载用户定义的接口实现(来自配置文件)

Eri*_*ric 3 java reflection interface dynamic instantiation

我需要允许用户在运行时通过配置文件指定接口的实现,类似于此问题: 在命令行参数中指定要使用的Java接口的实现

但是,我的情况有所不同,因为在编译时不了解实现,所以我将不得不使用反射来实例化该类。我的问题是...如何构造我的应用程序,以便我的类可以看到新实现的.jar,以便在我调用时可以加载该类:

Class.forName(fileObject.getClassName()).newInstance()
Run Code Online (Sandbox Code Playgroud)

mvr*_*ijn 5

评论正确。只要.jar文件在您的类路径中,就可以加载该类。

我过去曾使用过类似的方法:

public static MyInterface loadMyInterface( String userClass ) throws Exception
{
    // Load the defined class by the user if it implements our interface
    if ( MyInterface.class.isAssignableFrom( Class.forName( userClass ) ) )
    {
        return (MyInterface) Class.forName( userClass ).newInstance();
    }
    throw new Exception("Class "+userClass+" does not implement "+MyInterface.class.getName() );
}
Run Code Online (Sandbox Code Playgroud)

其中String userClass是配置文件中用户定义的类名。


编辑

想一想,甚至可以使用以下方式加载用户在运行时指定的类(例如,在上传新类之后):

public static void addToClassPath(String jarFile) throws IOException 
{
    URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class loaderClass = URLClassLoader.class;

    try {
        Method method = loaderClass.getDeclaredMethod("addURL", new Class[]{URL.class});
        method.setAccessible(true);
        method.invoke(classLoader, new Object[]{ new File(jarFile).toURL() });
    } catch (Throwable t) {
        t.printStackTrace();
        throw new IOException( t );
    }
}
Run Code Online (Sandbox Code Playgroud)

我记得addURL()在SO的某个地方使用反射找到了调用(当然)。