我有一个程序,我在运行时生成类(只包括变量和相关的getter和setter方法)。以后我想填充类。
获得类-我知道它的名字,但它不是在类路径-我尝试。forname(),但我总是得到一个ClassNotFoundException。
下面是我的例子:
Exception in thread "main" java.lang.ClassNotFoundException: com.test.wam.business.wsobjects.Testclass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at gui.Application.main(Application.java:94)
和代码:
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
DynamicURLClassLoader dynamicURLClassLoader = new DynamicURLClassLoader(urlClassLoader);
dynamicURLClassLoader.addURL(new URL("file://C:\dev\Eclipse_was\guitest\generated"));
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");
Object classInstance = c.newInstance();
ClassLoader:
public class DynamicURLClassLoader extends URLClassLoader {
public DynamicURLClassLoader(URLClassLoader classLoader) {
super(classLoader.getURLs());
}
@Override
public void addURL(URL url) {
super.addURL(url);
}
}
文件的完整限定名(使用eclipse -> copy完整限定名创建)
/guitest/生成/com/test/wam/business/wsobjects/Testclass.java
怎么了?
我可以看到两个问题:
1)您正在创建DynamicURLClassLoader
并向其添加URL,但您实际上没有使用它。这句话:
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");
将使用加载当前类的类加载器。这可能是应用程序的默认类装入器,但它肯定不是您刚刚创建的类装入器。javadoc说:
[
Class.forName(className)
]返回与给定字符串名称的类或接口相关联的Class
对象。调用此方法相当于:Class.forName(className, true, currentLoader)
,其中
currentLoader
表示当前类的定义类装入器。
所以…解决方案是:
Class c = Class.forName("com.test.wam.business.wsobjects.Testclass",
true, dynamicURLClassLoader);
2)这个字符串:
"file://C:\dev\Eclipse_was\guitest\generated"
不是一个有效的"file:" URL。您试图引用的路径的正确URL应该是:
"file:///C:/dev/Eclipse_was/guitest/generated"
您编写URL 的方式可能有效,但这不是正确的方法。参考:- Windows中的文件uri
方法Class.forName(String)
使用调用者类的ClassLoader
,如果你想使用特定的ClassLoader
来加载你的类,你需要使用Class.forName(String name, boolean initialize, ClassLoader loader)
代替下一个:
Class c = Class.forName(
"com.test.wam.business.wsobjects.Testclass", true, dynamicURLClassLoader
);
NB:当且仅当您提供给DynamicURLClassLoader
的URL
是有效的并且是您拥有类的父文件夹的路径时,这将起作用