获取DeclaredMethods反射和不在类路径中的类。

3

我正在使用反射从特定类中获取所有方法。

这个类引用了不在我的类路径中的类,因此我会收到一个异常:

java.lang.NoClassDefFoundError:

出错的原因是:

Method methods[] = theClass.getDeclaredMethods();

有没有办法“跳过”不在类路径中的所有内容?

你使用了什么方法来加载无法解析依赖项的类?通常情况下,当加载类而不是获取方法时,会出现NoClassDefFoundError错误。 - user545199
我正在使用theClass=Class.forName()。 - markiz
啊,好的,我想我看出你的问题了,我会发布一个详细的答案。 - user545199
1个回答

0

Class.forName()不会加载一个类,无论它是否在类路径中。它只会返回一个对已经加载的类的句柄。

一个类有两种主要的加载方式:

1.) 在import语句中引用该类(java.lang.*自动导入,因此java.lang包中的每个类都从一开始就被加载)

2.) 使用ClassLoader调用加载一个类,此时所有依赖项也将被解析和加载

因此,如果您想加载类路径之外的类或具有类路径之外的依赖项,则需要子类化ClassLoader并告诉它如何加载您的类及其依赖项。

请参阅ClassLoader规范:http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html

此外,还有现成的ClassLoader子类可供使用,例如URL ClassLoader,它可以让您简单地将ClassLoader实例指向路径,并加载该路径中的任何类。


如果我需要检查一个类(只是为了获取其中所有的方法),并且这个类(或这个类内部引用的其他类),那么我应该使用ClassLoader吗? - markiz
正确的做法是,在使用反射机制之前,必须先加载类,否则无法检查类。如果你只想查看方法名称而不加载类,则需要使用第三方Java库来解析.class文件,例如BCEL(字节码工程库),但这可能会增加额外的开销,这取决于你的需求。 - user545199
哦,另外,你可能想使用javap,它是大多数Java安装中找到的Java反汇编器。它还可以根据正确的参数告诉你方法名称。 - user545199
最后一个问题:如果找不到引用的类,我能跳过它而不会出现异常吗? - markiz
如果任何被引用的类无法解析,那么类加载器将无法加载该类,因此您可以始终为NoClassDefinitionError放置try-catch块,但是您将无法查看该类中的任何方法,至少在使用反射时不行。使用我提到的其他技术之一,您仍然可以这样做。使用BCEL,您甚至可以从一个类中提取一个函数并仅加载该函数。 - user545199

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接