今天来说一下Java中的反射技术,我个人十分喜欢反射技术,所以算是分享一下吧。
先说理论:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
以上取自百度百科,其实反射可以做很多好玩的事~比方说…好吧,我比不出来。看实战。
实战:
其实上面说的压缩成一句话就是:“可以在程序运行时读取/修改任意一个类的属性,调用方法”。
其实Java类中也就这两样东西,来看看具体的实现
我们建立一个狗狗类
怎么样非常简单暴力的一个类吧…就一个名称属性,和一个嚎叫方法。
然后建一个测试类,并在主方法内创建一个狗狗对象,然后为其属性赋值,最后调用他的嚎叫方法~。
为了完全不使用架包,所以就不使用Junit进行测试了,直接那main方法来。
看了上面的代码你一定发现有不合理的地方,哪有狗名叫哈士奇的,人家那是类别好吗,所以我们改一下~
这样看起来就好多了,这是简单的创建一个对象与为对象的属性赋值并执行方法,我们看一下结果:
已经成功的创建对象-为属性赋值-调用方法了….好吧废话先略过!
来用反射简单实现一下:
都知道Java里万物皆对象~,每个对象都属于一个类,但是类有属于谁(哪个类型)呢,注意我们说的不是继承,而是层次关系,其实类是属于“类型”这个类的…,好吧别打我,Java总有一个数据类型就是类,它就是Class 注意是大写的哦~,所有类的类型都是这个类。(当然这个类是属于谁的我就不知道了)。
怎么获得这个类的对象,我们来看看
这里有三种方式,第一种是根据对象的一个方法来获得,而第二个更简单,
第三个适用性较广,你想想一些框架的配置文件为啥是类全名吧 哈哈哈 不要在意第三个划红线了,它需要进行异常处理,因为如果你瞎输入个字符串,那么程序就懵逼了。
类型我们获得到了
继续~获得类的所有属性:
这里有两个方法,注释上已经写了区别,我们来稍稍修改一下程序类来测试一下
新增类:动物类
然后是修改狗狗类:
最后是:修改测试类
为啥这次没加黑框~因为我懒啊,看结果
确实符合~
getFields() :方法是获得类的公有属性,包含从父类继承的公有属性。
getDeclaredFields () :获得该类的所有属性,不包含继承来的。
然后获得一个指定的属性:
跟获得全部的条件一致。
好了,获得属性我们已经知道,接下来我们要读取或者设置类的属性,但是发现了一个严重的问题,就是现在根本没有对象,所以我们来根据类型创建一个对象。
很简单使用一个 newInstance()方法就直接获得了一个新的实例(对象)。
好吧我已经吧划黄线的删掉了,因为我们不会用到他了。
回到操作属性的问题,我们先来设置一下属性。
把这个新对象的名称设置为“二狗子”。这里使用有些局限性
设置就已经完成,注意如果属性是私有的必须设setAccessible(true),否则无法设置获得读取属性。obj对象的name属性已经等于“二狗子”了,这里不做测试了,读取完一起测试,我们现在来读取属性
读取完成,我们来看看输出结果:
设置属性与读取成功!
好了这就快了,我们继续来调用方法,首先需要获得方法与获得属性相同
权限与获得属性的权限一致。
然后讲一下获得一个指定的方法,我们获得一下狗狗的嚎叫方法,并打印结果,还是拿这个名为二狗子的对象。
代码:
结果:
哦了!调用方法成功。注意:虽然代码上没有写,但是如果要执行私有的方法必须也设置方法的Accessible为true这点与属性一致。
我们来个详细的执行带有返回值与参数的方法
我们先在狗狗类中添加一个无聊的方法
代码:
然后是测试代码:
最后是结果:
OK,成功,简单的反射技术就这些,唯一的难点就是获得方法时配置参数类型数组了,注意类型顺序要一致即可,还有属性与方法的Accessible还是不要设为true了,那样会降低安全性,可以先判断有没有该属性,如果有根据其名称获得其set或get方法比较好。
简单的反射大概就这样,我们来做个好玩的东西。
在手写JDBC访问数据库查询数据时,在处理返回数据时,我们每次都必须循环ResultSet来取值赋值,一张表必须有一次这个过程,无法避免。
现在我们假设你的实体(模型)类内的属性与数据库表中的字段一致一个不多一个不少,我们来写一个共同方法来读取resultSet。
代码:
两个实体类:
表:
角色表:
用户表:
最后一些代码:
连接相关方法:
主读取数据方法(无验证):
辅助方法两个:
最后测试方法:
结果:
可以看出类型是对的,优化一下:
测试方法:
执行结果:
妥妥的没问题!在加一个类也一样只要你跟数据库的表一致就可以,如果不一致就得依赖注解或者配置文件了- -!.
哈哈当然这个只是反射基础简单的练习,要想优化的的话还要考虑很多问题,我这里都没有做验证等。
好了,反射简单入门讲完了,整的比较啰嗦。以后有空分享点高级的…不说了还得去搬砖。