前言
日常开发中,我们可使用反射获取JavaBean的方法信息,而描述属性信息的就是Java Method,Method类同样位于java.lang.reflect包下。
Method
Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法),如果你想要通过反射调用类的私有方法时,要先在这个私有方法对应的Method对象上调用setAccessible来取消对这个方法的访问检查,再调用invoke方法来执行这个私有方法。
/**
* A {@code Method} provides information about, and access to, a single method
* on a class or interface. The reflected method may be a class method
* or an instance method (including an abstract method).
*
* <p>A {@code Method} permits widening conversions to occur when matching the
* actual parameters to invoke with the underlying method's formal
* parameters, but it throws an {@code IllegalArgumentException} if a
* narrowing conversion would occur.
*
* @see Member
* @see java.lang.Class
* @see java.lang.Class#getMethods()
* @see java.lang.Class#getMethod(String, Class[])
* @see java.lang.Class#getDeclaredMethods()
* @see java.lang.Class#getDeclaredMethod(String, Class[])
*
* @author Kenneth Russell
* @author Nakul Saraiya
*/
public final class Method extends Executable {
//.....
}
getModifiers
- 以整数形式返回由此Method对象表示的字段的Java语言修饰符(例如private、final、static等)。
@Data
public class User {
private String name;
private int age;
public void print(String name) {
if (null == name) {
return;
}
if (name.equals(this.name)) {
System.out.println(this.age);
}
}
}
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("print", String.class);
// public
System.out.println(Modifier.toString(method.getModifiers()));
}
getReturnType
- 返回一个Class对象,该对象描述了此Method对象所表示的方法的正式返回类型。
class User {
private String name;
private int age;
public int getAge(String name) {
if (null == name) {
return 0;
}
if (name.equals(this.name)) {
return this.age;
}
return 0;
}
}
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("getAge", String.class);
// int
System.out.println(method.getReturnType());
}
getName
- 以String形式返回此Method对象表示的方法名称。
class User {
private String name;
private int age;
public int getAge(String name) {
if (null == name) {
return 0;
}
if (name.equals(this.name)) {
return this.age;
}
return 0;
}
}
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("getAge", String.class);
// getAge
System.out.println(method.getName());
}
getParameterTypes
- 按照声明顺序返回Class对象的数组,这些对象描述了此Method对象所表示的方法的形参类型。如果底层方法不带参数,则返回长度为0的数组。
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("getAge", String.class);
// java.lang.String
Stream.of(method.getParameterTypes()).forEach(t-> System.out.println(t.getName()));
}
class User {
private String name;
private int age;
public int getAge(String name) {
if (null == name) {
return 0;
}
if (name.equals(this.name)) {
return this.age;
}
return 0;
}
}
getExceptionTypes
- 返回Class对象的数组,这些对象描述了声明将此Method对象表示的底层方法抛出的异常类型。如果此方法没有在其throws子句中声明异常,则返回长度为0的数组。
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("getAge", String.class);
// io.terminus.common.exception.ServiceException
Stream.of(method.getExceptionTypes()).forEach(t-> System.out.println(t.getName()));
}
class User {
private String name;
private int age;
public int getAge(String name) throws ServiceException {
if (null == name) {
return 0;
}
if (name.equals(this.name)) {
return this.age;
}
return 0;
}
}
getDeclaringClass
- 返回方法所在的类
public static void main(String[] args) throws Exception {
Method method = User.class.getMethod("getAge", String.class);
// class cn.gov.zcy.item.Test$User
System.out.println(method.getDeclaringClass());
}
class User {
private String name;
private int age;
public int getAge(String name) throws ServiceException {
if (null == name) {
return 0;
}
if (name.equals(this.name)) {
return this.age;
}
return 0;
}
}
invoke
- 对带有指定参数的指定对象调用由此Method对象表示的底层方法。
- 个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。
- 如果底层方法是静态的,那么可以忽略指定的obj参数。该参数可以为null。
- 如果底层方法所需的形参数为 0,则所提供的args数组长度可以为0或null。
- 如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在Java Language Specification, Second Edition 的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。
- 如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
public static void main(String[] args) throws Exception {
User user = new User();
Method setAgeMethod = user.getClass().getMethod("setAge", int.class);
Method setNameMethod = user.getClass().getMethod("setName", String.class);
setAgeMethod.invoke(user, 22);
setNameMethod.invoke(user, "晓断");
// User(name=晓断, age=22)
System.out.println(user);
}
@ToString
static
class User {
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}