Java 加载类,生成该类的对象

Java 加载类,生成该类的对象,java,class,dynamic,reflection,classcastexception,Java,Class,Dynamic,Reflection,Classcastexception,我是java反射/动态加载的初学者。我想从jar文件加载一个特定的类(实现一个接口)。此外,我还想初始化这个类的一个对象,并将其强制转换到我的特定接口 我尝试了.loadClass(),class.forName(),如果我将Myclass.newInstance强制转换到我的接口,我将得到一个ClassCastException 我如何编程我的插件加载器,让它在我的jar中加载我的类并将其转换到myInterface 编辑 我的服务器与我的插件实现的接口相同。现在我希望我的插件“加载”并转换到

我是java反射/动态加载的初学者。我想从jar文件加载一个特定的类(实现一个接口)。此外,我还想初始化这个类的一个对象,并将其强制转换到我的特定接口

我尝试了
.loadClass()
class.forName()
,如果我将
Myclass.newInstance
强制转换到我的接口,我将得到一个ClassCastException

我如何编程我的插件加载器,让它在我的jar中加载我的类并将其转换到
myInterface

编辑 我的服务器与我的插件实现的接口相同。现在我希望我的插件“加载”并转换到我的界面,这样我就可以正常使用它们了

编辑 下面是我试图消除这些错误的一些示例代码:D

URL url = f.toURL();  
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);

Class<ModInterface> c = (Class<ModInterface>)cl.loadClass("com.myapp.mod");

Class<? extends ModInterface> sub = c.asSubclass(ModInterface.class);
Constructor<? extends ModInterface> con = sub.getConstructor();
ModInterface mi = con.newInstance();
错误: 在您的帮助下,我完成了以下工作:

URL url = f.toURI().toURL();
   URL[] urls = new URL[]{url};
   ClassLoader loader = ModInterface.class.getClassLoader();
   ClassLoader cl = new URLClassLoader(urls, loader);
   Class<?> loadedClass = Class.forName("com.myapp.mod", true, cl);
   Class<? extends ModInterface> pluginClass = loadedClass.asSubclass(ModInterface.class);
   ModInterface mi = pluginClass.newInstance();

您似乎希望动态加载
接口
say
A
,以及实现类say
B
。您可以通过反射进行操作,如下所示:

Class<?> bClass = Class.forName("packagename.B", true, loader);
Class<?> aClass = Class.forName("packagename.A", true, loader);
Object bObject = // create an instance of class B via Reflection
Object aObject = aClass.cast(bobject);
Class-bClass=Class.forName(“packagename.B”,true,loader);
Class aClass=Class.forName(“packagename.A”,true,loader);
Object bObject=//通过反射创建类B的实例
对象aObject=aClass.cast(bobject);
请记住,这两个类定义都必须从一个类加载器加载,该类加载器是这两个类的共同父类。演员阵容的唯一目的是确定
B
确实是
a
的一个子类型

:

将对象强制转换为此类对象表示的类或接口


将帮助您了解如何以反射方式创建实例。

您似乎知道实现接口的类的具体名称,并且必须进行实例化。在这种情况下,以下各项将起作用:

考虑以下接口

package test.api;
public interface Plugin {
    void service();
}
通过以下实现

package test.impl;
import test.api.Plugin;
public class PluginImpl implements Plugin {
    @Override
    public void service() {
        System.out.println(":-)");
    }
}
然后,以下代码段将执行您想要的操作(并打印出“:-”):

Class loadedClass=Class.forName(“test.impl.PluginImpl”);
类
,之后必须强制转换。使用
Class.asSubClass
可以更好地进行此转换。如果加载的类没有实现该接口,则只会得到一个
ClassCastException

然而。。。如果你想建立一个简单的插件机制,你应该考虑使用A,这需要你的可插拔jar来定义一个服务配置文件。有关更多说明,请参阅链接


顺便说一句:代码示例中要加载的类看起来更像一个包名,因此无法找到它。也许这是你的问题?

我自己解决了我的问题。我已经完成了一个客户端库,它集成了我的ModInterface。之后,我将这个.jar添加到我的项目中,因此两者都有相同的Modinterface基础。在此步骤之后,ClassLoader.LoadClass可以在没有任何强制转换异常的情况下运行


谢谢您的帮助

想发布您尝试过的代码吗?另外,您是否有使用反射的理由?让编译器确保代码的类型安全通常是首选,除非您有一些必须推迟到运行时的事情。我有点失败,我想从Jar文件加载一个类,这个类实现一个接口。生成的对象应该被转换到这个已知的接口,这样我就可以在我的插件加载器中正常使用它了。不,我在发布代码方面没有问题,但我不能在8小时内回答我的主题,就像规则中显示的那样。你不需要回答你的主题。只需编辑您的问题并发布代码。添加的代码,希望您能帮助我:)没有必要在标题中添加主标记。我将此添加到上面的评论中,实际上我有一个接口,我的所有插件都必须实现。我的服务器也有这个接口,我只想加载一个类并将其强制转换到我的接口。这可能也是我的问题。我用jar的绝对路径获得了文件句柄,我在每个插件中定义了一个名为com.myapp.mod的路径。Mod是实现我的接口并被我的服务器识别的类。现在我尝试通过我的文件句柄加载该类,我知道我要加载的类名为com.myapp.mod。我的路径正确,并且找到了我的类,但是如果我尝试使用.asSubClass(..),我会得到一个错误。见上文。
Class<?> bClass = Class.forName("packagename.B", true, loader);
Class<?> aClass = Class.forName("packagename.A", true, loader);
Object bObject = // create an instance of class B via Reflection
Object aObject = aClass.cast(bobject);
package test.api;
public interface Plugin {
    void service();
}
package test.impl;
import test.api.Plugin;
public class PluginImpl implements Plugin {
    @Override
    public void service() {
        System.out.println(":-)");
    }
}
Class<?> loadedClass = Class.forName("test.impl.PluginImpl");
Class<? extends Plugin> pluginClass = loadedClass.asSubclass(Plugin.class);
Plugin plugin = pluginClass.newInstance();
plugin.service();