Java 加载类,生成该类的对象
我是java反射/动态加载的初学者。我想从jar文件加载一个特定的类(实现一个接口)。此外,我还想初始化这个类的一个对象,并将其强制转换到我的特定接口 我尝试了Java 加载类,生成该类的对象,java,class,dynamic,reflection,classcastexception,Java,Class,Dynamic,Reflection,Classcastexception,我是java反射/动态加载的初学者。我想从jar文件加载一个特定的类(实现一个接口)。此外,我还想初始化这个类的一个对象,并将其强制转换到我的特定接口 我尝试了.loadClass(),class.forName(),如果我将Myclass.newInstance强制转换到我的接口,我将得到一个ClassCastException 我如何编程我的插件加载器,让它在我的jar中加载我的类并将其转换到myInterface 编辑 我的服务器与我的插件实现的接口相同。现在我希望我的插件“加载”并转换到
.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();
您似乎希望动态加载
接口
sayA
,以及实现类sayB
。您可以通过反射进行操作,如下所示:
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();