简单入门Java反射

时间:2021-11-22 19:26:25

今天来说一下Java中的反射技术,我个人十分喜欢反射技术,所以算是分享一下吧。

 

先说理论:

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

以上取自百度百科,其实反射可以做很多好玩的事~比方说好吧,我比不出来。看实战。

 

 

实战:

其实上面说的压缩成一句话就是:“可以在程序运行时读取/修改任意一个类的属性,调用方法”。

其实Java类中也就这两样东西,来看看具体的实现

我们建立一个狗

简单入门Java反射

怎么样非常简单暴力的一个类吧就一个名称属性,和一个嚎叫方法

然后建一个测试类,并在主方法内创建一个狗狗对象,然后为其属性赋值,最后调用他的嚎叫方法~

简单入门Java反射

为了完全不使用架包,所以就不使用Junit进行测试了,直接那main方法来。

看了上面的代码你一定发现有不合理的地方,哪有狗名叫哈士奇的,人家那是类别好吗,所以我们改一下~

简单入门Java反射

这样看起来就好多了,这是简单的创建一个对象与为对象的属性赋值并执行方法,我们看一下结果:

简单入门Java反射

已经成功的创建对象-为属性赋值-调用方法了.好吧废话先略过!

来用反射简单实现一下:

都知道Java里万物皆对象~,每个对象都属于一个类,但是类有属于谁(哪个类型)呢,注意我们说的不是继承,而是层次关系,其实类是属于“类”这个类的,好吧别打我,Java总有一个数据类型就是类,就是Class 注意是大写的哦~,所有类的类型都是这个类。(当然这个类是属于谁的我就不知道了)。

 

怎么获得这个类的对象,我们来看看

简单入门Java反射

这里有三种方式,第一种是根据对象的一个方法来获得,而第二个更简单,

第三个适用性较广,你想想一些框架的配置文件为啥是类全名吧 哈哈哈 不要在意第三个划红线了,它需要进行异常处理,因为如果你瞎输入个字符串,那么程序就懵逼了。

 

类型我们获得到了

继续~获得类的所有属性:

简单入门Java反射

这里有两个方法,注释上已经写了区别,我们来稍稍修改一下程序类来测试一下

新增类:动物类

简单入门Java反射

然后是修改狗狗类:

简单入门Java反射

最后是:修改测试类

简单入门Java反射

为啥这次没加黑框~因为我懒啊,看结果

简单入门Java反射

确实符合~

getFields() :方法是获得类的公有属性,包含从父类继承的公有属性。

getDeclaredFields () :获得该类的所有属性,不包含继承来的。

 

 

然后获得一个指定的属性:

简单入门Java反射

跟获得全部的条件一致。

 

好了,获得属性我们已经知道,接下来我们要读取或者设置类的属性,但是发现了一个严重的问题,就是现在根本没有对象,所以我们来根据类型创建一个对象。

简单入门Java反射

 

很简单使用一个 newInstance()方法就直接获得了一个新的实例(对象)。

好吧我已经吧划黄线的删掉了,因为我们不会用到他了。

 

 

回到操作属性的问题,我们先来设置一下属性。

把这个新对象的名称设置为“二狗子”。这里使用有些局限性

简单入门Java反射

设置就已经完成,注意如果属性是私有的必须设setAccessible(true),否则无法设置获得读取属性。obj对象的name属性已经等于“二狗子”了,这里不做测试了,读取完一起测试,我们现在来读取属性

简单入门Java反射

读取完成,我们来看看输出结果:

简单入门Java反射

设置属性与读取成功!

 

好了这就快了,我们继续来调用方法,首先需要获得方法与获得属性相同

简单入门Java反射

权限与获得属性的权限一致。

然后讲一下获得一个指定的方法,我们获得一下狗狗的嚎叫方法,并打印结果,还是拿这个名为二狗子的对象。

 

代码:

简单入门Java反射

结果:

简单入门Java反射

哦了!调用方法成功。注意:虽然代码上没有写,但是如果要执行私有的方法必须也设置方法的Accessible为true这点与属性一致。

我们来个详细的执行带有返回值与参数的方法

我们先在狗狗类中添加一个无聊的方法

代码:

简单入门Java反射

然后是测试代码:

简单入门Java反射

最后是结果:

简单入门Java反射

 

OK,成功,简单的反射技术就这些,唯一的难点就是获得方法时配置参数类型数组了,注意类型顺序要一致即可,还有属性与方法的Accessible还是不要设为true了,那样会降低安全性,可以先判断有没有该属性,如果有根据其名称获得其set或get方法比较好。

简单的反射大概就这样,我们来做个好玩的东西。

在手写JDBC访问数据库查询数据时,在处理返回数据时,我们每次都必须循环ResultSet来取值赋值,一张表必须有一次这个过程,无法避免。

现在我们假设你的实体(模型)类内的属性与数据库表中的字段一致一个不多一个不少,我们来写一个共同方法来读取resultSet。

 

 

代码:

两个实体类:

简单入门Java反射

表:

角色表:

简单入门Java反射

用户表:

简单入门Java反射

最后一些代码:

连接相关方法:

简单入门Java反射

 

主读取数据方法(无验证):

简单入门Java反射

 

辅助方法两个:

简单入门Java反射

最后测试方法:

简单入门Java反射

结果:

简单入门Java反射

可以看出类型是对的,优化一下:

测试方法:

简单入门Java反射

 

执行结果:

简单入门Java反射

妥妥的没问题!在加一个类也一样只要你跟数据库的表一致就可以,如果不一致就得依赖注解或者配置文件了-  -!.

哈哈当然这个只是反射基础简单的练习,要想优化的的话还要考虑很多问题,我这里都没有做验证等。

 

 

好了,反射简单入门讲完了,整的比较啰嗦。以后有空分享点高级不说了还得去搬砖。