46 反射

作者: ca8519be679b | 来源:发表于2020-05-20 16:40 被阅读0次

反射,被称为框架设计的灵魂。

框架:半成品的软件,开发效率高,可以简化代码

概念:将类的各组成部分封装成其他对象,这就是反射机制

1

我们知道java代码在计算机中有三个阶段,如上图,第一阶段源代码阶段,。java代码写好后javac运行编译成字节码.class文件,这时代码是在计算机硬盘中,第三阶段是我们熟悉的运行阶段,创建对象,new之后调用属性方法,而第二阶段是将硬盘文件读取到内存中,是通过java的ClassLoader傀儡实现加载,将成员变量封装成Field,然后多成员变量即使用数组,构造方法封装成Constructor,成员方法封装成Method,其实这就是一种反射机制

反射的优点,可以在程序运行时调用对象,可以解耦,增加模块扩展性

为了获取类对象有3种方式:

1编译阶段,未加载到内存时,Class.forName("类名")将类加载到内存

2已经在内存中,使用 类名.class获取类对象

3运行阶段,有new出来的实例,使用实例.getClass()获取类对象,此方法继承自Object

2

如上,我们分别使用了3种方法实现获取类对象,其中因为forName方法要抛出异常,我们直接使用了基类Exception,类名字符串必须是包名拼接,我们可以看到3种方法输出一样,同时==来比较这些类对象是否是同一个对象,可以得出结论,class在程序当次运行时只会加载一次(其实Class默认还有泛型,但是我们右侧是指定类型,所以左侧可以省略)

三种方法,Class.forName方法多用于配置文件,读取文件,加载类

第二种用于传参,第三种只是利用对象获取字节码class

Class对象的各种获取方法

3

我们获得了字节码对象后,如之前讲的,可以通过各种方法获取成员变量,构造方法,成员方法,还有类名,对应还有获取所有和获取单个的,还有获取一般和Declared的,这个后面讲讲Declared是干嘛用的,我们功能分别讲解

获取Field成员变量

4

还是针对上次使用的Person类,我们定义了无参和有参的构造,getter和setter,还设置了toString方法

Field[] getFields()方法

5

如上,获取类就用Person.class,我们遍历Fields数组,打印发现什么都没有,所以getFields[]返回的其实是public属性

6

如上,我们添加几个公有的public属性,可以被打印出来

7

为了进一步确定,我们添加默认和protected属性,结果一致

Field getField(String name)方法  根据指定public属性名获取Field方法

8

如上,我们定义了a为public属性,那么就可以获取,如上可以打印出来,但是我们获取到Field对象有什么用呢,

9

我们查看文档可以看到Field成员方法,get和set方法,get获取属性值,set给属性设置值,因此我们获取到对象和类就可以给其设置值

10

代码如上,为了给参数传入obj,我们实例对象p,a属性默认是int为0,我们设置值后变成33

Field[] getDeclaredFields()方法

11

我们运行可以发现,所有成员变量都打印了出来,不论是public,protected,默认,private

Field getDeclaredField()方法

同样,你会认为其是获得不受限的成员属性,其实访问private时报错

12

如上,因为私有属性本身还是有保护性的,但是也不是不能访问到

13

我们这里需要使用暴力反射Field对象的setAccessible(Boolean)方法,设置为true,我们就可以访问

获取Constructor构造方法

14

如上,我们使用getConstructor方法获取Constructor构造器对象,我们可以指定无参或者有参,有参数的时候,需要使用对应类型的class对象,我们获取到Constructor构造器对象,需要关注的方法就是其newInstance方法,创建实例,我们可以将其打印查看结果

15

当然,视频里还说无参情况下可以直接使用class对象的newInstance方法,但是IDE给标横线证明是废弃了,至于获取构造器的其他3个方法,很少用,如果有私有的构造方法,我们记得要使用setAccessible来解决调用问题

获取Method成员方法

16

我们先运行class的getMethods(),可以遍历看到打印的是所有的public方法,包括继承自父类Object的方法

17

我们给Person添加2个eat方法,一个无参,一个传入字符串

18

使用getMethod,可以指定对象名,我们尝试打印这个Method对象如上

当然,我们获得Method成员方法,是希望能运行,而不只是打印函数名Method对象,有方法invoke(Object obj,...参数列表)

19

如上,我们就分别实现了调用对象的2个eat方法

当然Method对象还有getName获得方法名

反射案例

我们写了很多反射相关的,感觉有的是很墨迹,没有体验到其优秀之处,这里一个案例展示(是黑马视频的案例,要求根据用户配置好的文件,实现创建配置文件指定类,并使用其方法,视频里会说虽然我们现在有Person类,但是还可能有Student类啊,还可能有其他方法啊巴拉巴拉。。)

20

视频里介绍配置文件使用.properties后缀存,为什么呢,后续讲,里面写上我们配置的类名和方法名,=连接右侧无引号,如上即编写完毕,其中类名要加上包名

21

如上,需要注意的是使用Properties类,可以使用load方法,加载结果存储类似map结构,要求传入的是inputStream,我们可以实例输入流,但是其实我们有类加载器,使用类加载器可以使用其getResourceAsStream获得,pro对象load就可以使用getProperty获得=右侧值,我们就获得了类名和方法名,其他调用就没什么说的了(我们查看框架的配置文件,有时候看见类名,就可以知道使用的是反射机制)

相关文章

  • 46 反射

    反射,被称为框架设计的灵魂。 框架:半成品的软件,开发效率高,可以简化代码 概念:将类的各组成部分封装成其他对象,...

  • 室内设计,3dmax材质教程,透明塑料材质

    今天教大家做一个透明塑料的材质。 1先创建一个VRaymtl标准材质 2漫反射颜色设置为46 、90 、172。 ...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

网友评论

      本文标题:46 反射

      本文链接:https://www.haomeiwen.com/subject/hfgyohtx.html