试用Java中的反射reflect之getDeclaredMethods和getMethods
目的:根据类名、方法名以及方法对应的参数,获取方法,并实现方法的调用
1、getDeclaredMethods和getMethods的区别
Method | getDeclaredMethod(String name, Class... parameterTypes) Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object. |
Method[] | getDeclaredMethods() Returns an array of Method objects reflecting all the methods declared by the class or interface represented by this Class object. |
Method | getMethod(String name, Class... parameterTypes) Returns a Method object that reflects the specified public member method of the class or interface represented by this Class object. |
Method[] | getMethods() Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces. |
由此可见,getDeclaredMethod*()获取的是类自身声明的所有方法,包含public、protected和private方法。getMethod*()获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。
实例一:getDeclaredMethod和getMethod的区别
Say.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package
pkg.reflection;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method;
public
class
Say {
public
void
say(String methodStr,String name,
int
age)
throws
SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
// Method method = this.getClass().getMethod("say" + methodStr, new Class[]{String.class,int.class}); //1
Method method =
this
.getClass().getDeclaredMethod(
"say"
+ methodStr,
new
Class[]{String.
class
,
int
.
class
});
//2
method.invoke(
this
,
new
Object[]{name,age});
}
public
void
sayHello(String name,
int
age){
System.out.println(
"hello "
+ name +
",I know you are "
+ age);
}
protected
void
sayHi(String name,
int
age){
System.out.println(
"hi "
+ name +
",I know you are "
+ age);
}
private
void
sayBye(String name,
int
age){
System.out.println(
"bye "
+ name +
",I know you are "
+ age);
}
}
|
SayTest.java
1
2
3
4
5
6
7
8
9
10
11
|
package
pkg.reflection;
import
java.lang.reflect.InvocationTargetException;
public
class
SayTest {
public
static
void
main(String[] args)
throws
SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
new
Say().say(
"Hello"
,
"jianjianjiao"
,
22
);
new
Say().say(
"Hi"
,
"jianjianjiao"
,
22
);
}
}
|
当使用say方法里的//1语句时,main函数抛出异常,可见使用getMethod时,因为sayHi是保护方法,获取方法sayHi失败
1
2
3
4
5
6
|
<SPAN style=
"FONT-SIZE: 14pt"
>hello jianjianjiao,I know you are
22
Exception in thread
"main"
java.lang.NoSuchMethodException: pkg.reflection.Say.sayHi(java.lang.String,
int
)
at java.lang.Class.getMethod(Unknown Source)
at pkg.reflection.Say.say(Say.java:
9
)
at pkg.reflection.SayTest.main(SayTest.java:
27
)
</SPAN>
|
当使用say方法里的//2语句时,可以正常调用
1
2
|
hello jianjianjiao,I know you are
22
hi jianjianjiao,I know you are
22
|
可见,不能用java.lang.Class.getMethod方法获取自身的非public方法,用java.lang.Class.getDeclaredMethod方法可以。
实例二:getDeclaredMethods和getMethods的区别
ReflectionUtils.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
pkg.reflection;
import
java.lang.reflect.Method;
public
class
ReflectionUtils {
public
static
void
getMethodDeclaration(Class<?> clazz){
Method[] methods = clazz.getDeclaredMethods();
System.out.println(
"MethodDeclaration in "
+ clazz.getName());
for
(Method method : methods){
method.setAccessible(
true
);
System.out.println(method.getName());
}
}
public
static
void
getMethod(Class<?> clazz){
Method[] methods = clazz.getMethods();
System.out.println(
"Method in "
+ clazz.getName());
for
(Method method : methods){
System.out.println(method.getName());
}
}
}
|
测试类 SayTest.java
1
2
3
4
5
6
7
8
9
10
11
|
package
pkg.reflection;
import
java.lang.reflect.InvocationTargetException;
public
class
SayTest {
public
static
void
main(String[] args)
throws
SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException{
ReflectionUtils.getMethod(Say.
class
);
ReflectionUtils.getMethodDeclaration(Say.
class
);
}
}
|
输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
Method in pkg.reflection.Say
say
sayHello
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
MethodDeclaration in pkg.reflection.Say
say
sayHello
sayHi
sayBye
|
可见,调用getMethods方法输出的是自身的public方法和父类Object的public方法。调用getDeclaredMethods方法输出的是自身的public、protected、private方法。