Java编程开发学习之Java反射
小职 2021-05-08 来源 :狼王编程 阅读 424 评论 0

摘要:本文主要介绍了Java编程开发学习之Java反射,通过具体的内容向大家展现,希望对大家Java开发的学习有所帮助。

本文主要介绍了Java编程开发学习之Java反射,通过具体的内容向大家展现,希望对大家Java开发的学习有所帮助。

Java编程开发学习之Java反射

这篇让我们聊聊什么是反射,为啥好多程序员听到反射就莫名的害怕呢,本文给你壮壮胆,其实没多少东西的!

 

在Java中,想要运行时操作对象的方法、属性,其中有效的手段,就有反射。这也是框架最常使用的手段,因为框架在编译时并不知晓系统中有哪些类会被使用。

 

Java中对象的类型信息在运行时由Class对象表示,Class对象是伴随类加载而实例化产生的,而反射的实现就围绕着Class对象。

 

有很多种方式可以获取类的Class对象,包括:

 

Class<Object> c1 = Object.class;

Class<?> c2 = Class.forName("java.lang.Object");

Class<?> c3 = new Object().getClass();

反射可以做什么?

 

1. 实例化对象

 

对象的实例化,可以通过new关键字直接实例化,也可以通过反射,例如:

 

class.newInstance()  

class.getConstructor(Class<?>... parameterTypes).newInstance(Object ... initargs)

为什么需要用反射来进行对象实例化?

 

有不能使用new关键字直接实例化对象的场景,例如:Spring容器管理的Bean,只能通过类的全限定名加载类,然后反射实例化。

 

在不想使用new关键字的场景,目的是为了简化编程,使代码美观,可能大家经常看到类似的用法,例如:

 

public static <T> T parseObject(String text, Class<T> clazz) {

  return parseObject(text, clazz, new Feature[0]);

}

/**

* 简单的复制出新类型对象

*/

public static <S, D> D map(S source, Class<D> destinationClass){

  return mapper.map(source, destinationClass);

}

2. 筛选合适的类

 

实际开发中,经常会有这种需要,如果类有某某特征,就进行某某操作。在Spring进行扫描的时候,我们会通过过滤器,来精细化控制bean的生成,包括:

 

根据isInstance(Object obj)判断是否实现某某接口或者继承特殊的父类;

根据isAnnotationPresent(Class annotationClass)判断是否被注解标记。

3. 方法调用

 

有些场景不能或者不合适直接调用方法,例如:我们处理HTTP请求,需要从URI映射到方法调用,如果我们能够穷举所有的URL到对象方法的映射关系,那么也没问题,但是无数的if条件判断,显然不是明智的选择。

 

通常我们先会获取资源对象,然后反射调用对象的方法。

 

Method.invoke(Object obj, Object... args)

如何获取对象的方法对象,也就是Method对象呢?Class类提供了以下实现:

 

Method[] getMethods();

Method[] getDeclaredMethods();

Method getMethod(String name, Class<?>... parameterTypes);

Method getDeclaredMethod(String name, Class<?>... parameterTypes);

这些方法可以分为两类:

 

方法签名中带有Declared的,会在当前类的所有方法中查找,但不会遍历父类。

不带Declared的会遍历所有父类,但只会查找public方法。

推荐使用工具类:org.apache.commons.lang3.reflect.MethodUtils 此类中包含遍历所有父类查找方法、当前类查找public方法或者反射执行方法的便捷操作。

 

4. 属性操作

 

Class.getFields(), Class.getField(String),  

Class.getDeclaredFields(), Class.getDeclaredField(String)

命名规则同方法,推荐使用工具类:org.apache.commons.lang3.FieldUtils,进行读取或者赋值操作。

 

反射进行赋值有几点需要注意:

 

如果不为public类型,那么设置字段前必须通过Field.setAccessible(true)方法进行访问权限设置,不然会抛出异常:IllegalAccessException 。

如果字段为static类型,那么通过set方法进行赋值时,会忽略obj对象,因为静态字段属于类。

如果字段为final类型,不管是public还是 private,那么用set方法赋值时,只有setAccessible进行访问权限设置后,才能正确调用,不然会报异常:IllegalAccessException。但是对final字段进行set方法赋值时,尽管方法正常调用,但是并不会改变fianl字段的值。

如果字段为final static 类型,那么进行set方法赋值时,总会抛出IllegalAccessException异常。

最后如果对当前对象的所有方法,或者所有字段进行某种操作,那么推荐工具类:org.springframework.util.ReflectionUtils

 

4、总结

 

所以反射其实没那么可怕,消灭恐惧的最好办法就是面对恐惧,加油学起来吧!


我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取基础课程·答疑解惑·职业测评

Java编程开发学习之Java反射

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程