反射类以及ReflectionUtils类的使用

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

如下获取对应的方法执行结果,method为需要执行的方法,可写在一个枚举中动态获取
 Method method  = UserService.getClass().getMethod("method",User.class);
 result = (List<String>)method.invoke(UserService, args);

 JAVA反射的方法主要有三种:Class,Method,Field。
 Field获取对象的属性
获取Field的常用方法:

getFields():获取public类型的属性(也可以获取到父类的public修饰的属性)并返回一个Field数组;

getDeclaredFields(): 获取所有属性(包括public、protected、default、private权限类型,但不能获取继承父类的属性)并返回一个Field数组;

getField(String name):获取特定的public对象属性,name为属性名;

getDeclaredField(String name): 获取特定的对象属性,属性的访问权限可以是public、protected、default、private,name为属性名;

例如:

User user = new User();
user.setName("zhangsan");
 // getDeclaredField可以获取私有属性
 Field field = User.class.getDeclaredField("name");
 // 设置该属性可以被访问(如果没有这步,你拿到了Field对象但是不能拿到值)
 field.setAccessible(true);
 // 将对象传入,这里很多人会有误区,为什么要传对象,不传对象不能拿到值吗?
 // 答:不传拿不到值,因为,Class对象是单例(属于类的),你不指定对象,则拿不到值
String name = (String) field.get(user);

(2)Field对象的常用方法:

getType():返回Field对象的类型

getName():返回Field对象的名字

set(Object obj,Object value):设置对象属性的值,obj为实例对象,value为要为属性设置的新值

2.Method
获取对象方法,执行对象方法

继承的方法(包括重载、重写和隐藏的)会被编译器强制执行,这些方法都无法反射。

(1)获取Method对象的方法

getMethod(String name,Object type):获取特定的public对象方法,name为方法名,type为参数类型;

getDeclaredMethod(String name,Object type): 获取特定的对象方法,属性的访问权限可以是public、protected、default、private,name为方法名,type为参数类型;

(2)Method对象的常用方法:

getReturntype():获取Method对象返回类型

getName():返回Method对象的名字

invoke(Object obj,Object value):执行对象方法,obj为实例对象,value为方法参数,没有参数写null

Spring中ReflectionUtils常用方法详解

Spring针对反射提供的工具类:ReflectionUtils。反射在容器中使用是非常频繁的了,ReflectionUtils中也提供了想当多的有用的方法,一起来看看。

在ReflectionUtils中提供了一些专门用于处理在反射中异常相关的方法,这些方法一般在Spring框架内部使用,当然,出于规范考虑,我们在开发中涉及到反射的异常,也可以使用这些方法。

调用method方法:invokeMethod(Method method, Object target)

//遍历所有方法
doWithMethods(Class targetClass, MethodCallback mc)
获取类的所有的方法的:getAllDeclaredMethods(Class leafClass)
用于对象的拷贝的方法(类必须是同一类或子类):shallowCopyFieldState(final Object src, final Object dest)

找到所有的bean中TestClass.class注解
Map<String ,Object> beans = getApplicationContext().getBeansWithAnnotation(TestClass.class);
for(Object bean : beans.values()) {

logger.info("测试类{}", bean.getClass().getName());

//遍历bean的所有method,m为里面的Method,m.isAnnotationPresent为判断method上面是否有TestMethod注解做为条件

ReflectionUtils.doWithMethods(bean.getClass(), m->testMethod(bean, m), m->m.isAnnotationPresent(TestMethod.class));
}

*Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) *
在类型clazz上,查询name方法,参数类型列表为paramTypes;
查找属性Field findField(Class<?> clazz, String name)
查找所有属性:Field[] fields = getDeclaredFields(searchType);

//在method,class,Field上面查找的一个SpanCustomizer注解
找method上面的一个SpanCustomizer注解
AnnotatedElementUtils.findMergedAnnotation(method, SpanCustomizer.class);

找Field上面的一个SpanCustomizer注解
AnnotatedElementUtils.findMergedAnnotation(field, SpanCustomizer.class);

找User类上面的一个SpanCustomizer注解
AnnotatedElementUtils.findMergedAnnotation(user.class, SpanCustomizer.class);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值