Java 通过反射获取给定类的可访问方法列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1857775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting a list of accessible methods for a given class via reflection
提问by ChssPly76
Is there a way to get a list of methods that would be accessible (not necessarily public) by a given class? The code in question will be in a completely different class.
有没有办法获得一个给定类可以访问(不一定是公共的)的方法列表?有问题的代码将在一个完全不同的类中。
Example:
例子:
public class A {
public void methodA1();
protected void methodA2();
void methodA3();
private void methodA4();
}
public class B extends A {
public void methodB1();
protected void methodB2();
private void methodB3();
}
For class B
I'd like to get:
对于课堂,B
我想得到:
- all of its own methods
methodA1
andmethodA2
from classA
methodA3
if and only if classB
is in the same package asA
- 所有它自己的方法
methodA1
并且methodA2
从课堂上A
methodA3
当且仅当类B
与A
methodA4
should never be included in results because it's inaccessible to class B
. To clarify once again, code that needs to find and return the above methods will be in a completely different class / package.
methodA4
永远不应该包含在结果中,因为 class 无法访问它B
。再次澄清,需要查找和返回上述方法的代码将位于完全不同的类/包中。
Now, Class.getMethods()
only returns public methods and thus won't do what I want; Class.getDeclaredMethods()
only returns methods for current class. While I can certainly use the latter and walk the class hierarchy up checking the visibility rules manually, I'd rather not if there's a better solution. Am I missing something glaringly obvious here?
现在,Class.getMethods()
只返回公共方法,因此不会做我想做的事;Class.getDeclaredMethods()
只返回当前类的方法。虽然我当然可以使用后者并手动检查类层次结构,但如果有更好的解决方案,我宁愿不这样做。我在这里遗漏了一些明显的东西吗?
采纳答案by cletus
Use Class.getDeclaredMethods()
to get a list of all methods (private or otherwise) from the class or interface.
用于Class.getDeclaredMethods()
从类或接口获取所有方法(私有或其他)的列表。
Class c = ob.getClass();
for (Method method : c.getDeclaredMethods()) {
if (method.getAnnotation(PostConstruct.class) != null) {
System.out.println(method.getName());
}
}
Note:this excludes inherited methods. Use Class.getMethods()
for that. It will return all publicmethods (inherited or not).
注意:这不包括继承的方法。Class.getMethods()
为此使用。它将返回所有公共方法(继承与否)。
To do a comprehensive list of everything a class can access (including inherited methods), you will need to traverse the tree of classes it extends. So:
要完整列出一个类可以访问的所有内容(包括继承的方法),您需要遍历它扩展的类树。所以:
Class c = ob.getClass();
for (Class c = ob.getClass(); c != null; c = c.getSuperclass()) {
for (Method method : c.getDeclaredMethods()) {
if (method.getAnnotation(PostConstruct.class) != null) {
System.out.println(c.getName() + "." + method.getName());
}
}
}
回答by PSpeed
Pretty sure you will have to walk up the superclass
es to get what you want. After all, that's what getMethods()
is doing with the getDeclaredMethods()
call internally (sort of... it actually calls a private
version that filters out non-public
methods but it does traverse up the class
tree to build the full list).
很确定你必须走上superclass
es才能得到你想要的东西。毕竟,这getMethods()
就是getDeclaredMethods()
内部调用的作用(有点......它实际上调用了一个private
过滤掉非public
方法的版本,但它确实遍历class
树以构建完整列表)。
Curious why such a thing is needed, though.
不过很好奇为什么需要这样的东西。
回答by Johan Kaving
As cletus and PSpeed has already answered - you need to traverse the inheritance tree of classes.
正如 cletus 和 PSpeed 已经回答的那样 - 您需要遍历类的继承树。
This is the way I do it, but without handling package private methods:
这是我这样做的方式,但不处理包私有方法:
public static Method[] getAccessibleMethods(Class clazz) {
List<Method> result = new ArrayList<Method>();
while (clazz != null) {
for (Method method : clazz.getDeclaredMethods()) {
int modifiers = method.getModifiers();
if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) {
result.add(method);
}
}
clazz = clazz.getSuperclass();
}
return result.toArray(new Method[result.size()]);
}
I am using it in a backwards-compatibility checker where I know that the classes that might be affected will not be in the same package anyway.
我在向后兼容性检查器中使用它,我知道可能受影响的类无论如何都不会在同一个包中。
回答by Alluir
A point on Cletus's answer (I can't comment there because I don't have enough reputation.). Anyway, Cletus's code did not work for me (Eclipse was also complaining about it), probably due to changes in Java since 2009.
关于 Cletus 的回答的一点(我无法在那里发表评论,因为我没有足够的声誉。)。无论如何,Cletus 的代码对我不起作用(Eclipse 也在抱怨它),可能是由于自 2009 年以来 Java 的变化。
The line:
线路:
for (Class c = ob.getClass(); c != null; c = c.getSuperclass()) {
had to be changed to:
必须改为:
for (Class<?> c = ob.getClass(); c != null; c = c.getSuperclass()) {
to get any output at all. So the complete code for me was (including input argument types, modifiers and return type):
获得任何输出。所以对我来说完整的代码是(包括输入参数类型、修饰符和返回类型):
for (Class<?> c = scanner.getClass(); c != null; c = c.getSuperclass()) {
System.out.println(c.getName());
for (Method method : c.getMethods()) {
System.out.println("\t" + Modifier.toString(method.getModifiers())
+ " " + method.getName());
for (Class<?> param: method.getParameterTypes()) {
System.out.println("\t\t" + param.getName());
}
System.out.println("\t\t == returns ==> "
+ method.getReturnType().getName());
}
}