Spring:ReflectionUtils工具类使用二:Method
1 Method相关使用
(1)ReflectionUtils.getDeclaredMethods、ReflectionUtils.makeAccessible、ReflectionUtils.invokeMethod使用:
package com.xiaoxu.base;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author xiaoxu
* @date 2022-02-21
* Ymybatis:com.xiaoxu.base.FruitMethod
*/
public class FruitMethod extends BaseFruit{
void perFruit(String name){
System.out.printf("我是水果:%s%n",name);
}
static void isFruit(){
System.out.println("我是isFruit方法");
}
String print(){
System.out.println("我是print方法");
return "abc";
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Class<FruitMethod> clazz = FruitMethod.class;
FruitMethod f= clazz.newInstance();
//ReflectionUtils.getDeclaredMethods不会获取继承的父类的方法
Method[] declaredMethods = ReflectionUtils.getDeclaredMethods(clazz);
Arrays.stream(declaredMethods).forEach(m->{
System.out.println(m);
if("perFruit".equals(m.getName())||"isFruit".equals(m.getName())||"print".equals(m.getName())){
//不使用makeAccessible(method)抛错:Could not access method or field
//不使用该方法,实例void方法perFruit、实例返回String方法print、类方法(static修饰)isFruit无法使用invokeMethod
ReflectionUtils.makeAccessible(m);
System.out.printf("我是方法的参数个数:%s%n",m.getParameterCount());
if(m.getParameterCount()!=0){
// 本质是调用的method.invoke()方法,可以执行方法
ReflectionUtils.invokeMethod(m,f,"猕猴桃");
}else{
ReflectionUtils.invokeMethod(m,f);
}
}
System.out.println("*******************");
});
}
}
class BaseFruit{
void sale(){}
static void eat(){}
}
执行结果如下:
public static void com.xiaoxu.base.FruitMethod.main(java.lang.String[]) throws java.lang.InstantiationException,java.lang.IllegalAccessException
*******************
java.lang.String com.xiaoxu.base.FruitMethod.print()
我是方法的参数个数:0
我是print方法
*******************
static void com.xiaoxu.base.FruitMethod.isFruit()
我是方法的参数个数:0
我是isFruit方法
*******************
private static void com.xiaoxu.base.FruitMethod.lambda$main$0(com.xiaoxu.base.FruitMethod,java.lang.reflect.Method)
*******************
void com.xiaoxu.base.FruitMethod.perFruit(java.lang.String)
我是方法的参数个数:1
我是水果:猕猴桃
*******************
(2)ReflectionUtils.findMethod(搭配ReflectionUtils.makeAccessible、ReflectionUtils.invokeMethod)使用:
package com.xiaoxu.base;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
/**
* @author xiaoxu
* @date 2022-02-22
* Ymybatis:com.xiaoxu.base.FruitMethod2
*/
public class FruitMethod2 extends BaseFruit2{
void perFruit(String name){
System.out.printf("我是水果:%s%n",name);
}
static void isFruit(){
System.out.println("我是isFruit方法");
}
String print(){
System.out.println("我是print方法");
return "abc";
}
Object invokeMethod(Object target,String methodName,Object... args){
Method method;
if(args==null||args.length==0){
method = ReflectionUtils.findMethod(target.getClass(),methodName);
Assert.notNull(method, () -> "method不能为空,请检查方法名称是否存在");
ReflectionUtils.makeAccessible(method);
return ReflectionUtils.invokeMethod(method,target);
}else{
// 初始化的Class<?>数组,里面是Class对象,为引用对象,数组初始值aClass为null
Class<?>[] c = new Class[args.length];
for (int i = 0; i < c.length; i++) {
c[i] = args[i].getClass();
}
method = ReflectionUtils.findMethod(target.getClass(),methodName,c);
Assert.notNull(method, () -> "method不能为空,请检查存在参数的该方法名称是否存在");
ReflectionUtils.makeAccessible(method);
return ReflectionUtils.invokeMethod(method,target,args);
}
}
public static void main(String[] args) {
Class<?> clazz = FruitMethod2.class;
FruitMethod2 f = new FruitMethod2();
f.invokeMethod(f,"eat");
f.invokeMethod(f,"perFruit","苹果");
}
}
class BaseFruit2{
void sale(){
System.out.println("我是父类的sale方法");
}
static void eat(){
System.out.println("我是父类的eat方法");
}
}
(3)ReflectionUtils.doWithMethods、ReflectionUtils.isToStringMethod使用:
package com.xiaoxu.base;
import lombok.SneakyThrows;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author xiaoxu
* @date 2022-02-22
* Ymybatis:com.xiaoxu.base.FruitMethod3
*/
public class FruitMethod3 extends BaseFruit3{
private String name;
void perFruit(String name){
System.out.printf("我是水果:%s%n",name);
}
static void isFruit(){
System.out.println("我是isFruit方法");
}
String print(){
System.out.println("我是print方法");
return "abc";
}
void doWithMyMethods(Class<?> clazz){
Assert.notNull(clazz,()-> "Class数据不能为空");
Assert.notEmpty(clazz.getDeclaredMethods(),()->"Class的方法不能为空");
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
@SneakyThrows
@Override
public void doWith(@NonNull Method method) throws IllegalArgumentException, IllegalAccessException {
System.out.println("我是筛选后的方法:");
System.out.println(method);
if(ReflectionUtils.isToStringMethod(method)){
System.out.println("我是toString:"+ReflectionUtils.invokeMethod(method, clazz.newInstance()));
}
}
}, new ReflectionUtils.MethodFilter() {
@Override
public boolean matches(@NonNull Method method) {
return Arrays.asList(new String[]{"eat", "isFruit", "print","toString"}).contains(method.getName());
}
});
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Class<FruitMethod3> clazz = FruitMethod3.class;
FruitMethod3 fruitMethod3 = clazz.newInstance();
fruitMethod3.doWithMyMethods(clazz);
}
@Override
public String toString() {
return "水果3{" +
"name='" + name + '\'' +
'}';
}
}
class BaseFruit3{
void sale(){
System.out.println("我是父类的sale方法");
}
static void eat(){
System.out.println("我是父类的eat方法");
}
}
执行结果如下:
我是筛选后的方法:
public java.lang.String com.xiaoxu.base.FruitMethod3.toString()
我是toString:水果3{name='null'}
我是筛选后的方法:
java.lang.String com.xiaoxu.base.FruitMethod3.print()
我是筛选后的方法:
static void com.xiaoxu.base.FruitMethod3.isFruit()
我是筛选后的方法:
static void com.xiaoxu.base.BaseFruit3.eat()
我是筛选后的方法:
public java.lang.String java.lang.Object.toString()
我是toString:水果3{name='null'}
常用方法见上,其余方法用法类似,不一一赘述。