我有一些代码在特定的地方使用反射来实例化一些像这样的对象:
String className = type.toString();
Class klass = Class.forName(className);
在正常环境中运行时,这段代码可以正常工作。但是,当我尝试对运行这两行的方法进行单元测试时,我不断获得java.lang.ClassNotFoundException
例外。
起初我认为这与我试图实例化的类没有被包含在类路径中这一事实有一些奇怪的原因。所以我接着这样做了:
// Where type variable points to java.lang.String rather than my own class
String className = type.toString();
Class klass = Class.forName(className);
然而它仍然失败:
java.lang.ClassNotFoundException: class java.lang.String
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:348)
我一直在调查ClassLoader并试图确定为什么它似乎找不到任何类但无济于事。
有人知道为什么只有在TestNG运行代码时才会发生这种情况以及该怎么办?
答案 0 :(得分:5)
好的,我能够搞清楚。当然,这是非常愚蠢的,让你质疑你作为软件工程师的所有岁月。
问题在于这一行:
String className = type.toString();
值类型属于java.lang.reflect.Type类。
你能看到这个问题吗?如果你不能,那就不要感到难过,因为我也不能。
如果您运行此代码:
System.out.println(type.toString());
System.out.println(type.getTypeName());
您最终得到以下输出:
class java.lang.String
java.lang.String
问题非常明显,我应该使用getTypeName()
而不是toString()
。当然它会抛出ClassNotFoundException
因为class<SPACE>
在实际的类名之前。
然而,当我查看堆栈跟踪时,我忽略了它在类名前有class<SPACE>
。
叹息。然而,好时光了解了班级装载机。