Java 基础系列: 反射
开始想要做数据的念头比较晚,而大多数的大数据都是 Java 开发的,学习 Java 也逐渐排上日程,这一系列的相关主题是随着学习大数据相关技术的过程中对于一些疑问和技术点,逐渐完善补充的。希望这趟旅程可以收获和分享知识。
本文从问题的角度,了解反射,会从以下几个角度进行解析:
什么是反射,反射的概念以及可以获取到的信息
如何使用反射
如何利用反射并结合 Flink 中类型定义的角度解析反射的应用
什么是反射
反射就是 Reflection,Java 中超类是Object
类,即所有的 Java 类都是Object
类。Java 的反射解决的是程序在运行期可以拿到Class
对象的所有信息。对于 Java 小白这里涉及两个问题:
什么是
Class
对象?Class
对象包含哪些信息?
下面就从这两个角度进行更深入的了解。
Class 对象
Class 对象在编译阶段编译器在.class
文件中生成Class
对象,在加载阶段,通过 JVM 加载机制将其加载到内存中。反射是在运行阶段获取 Class 对象的信息。
在 Java 中有两种对象:
Class 对象:Class 对象是 JVM 生成用来保存对象的类的信息的。
实例对象:实例对象是类的实例,通常是通过
new
关键字构建的。
Java 程序执行之前需要经过编译、加载、链接和初始化几个阶段,编译阶段会将源码文件编译为
.class
字节码文件,编译器同时会在.class
文件中生成 Class 对象,加载阶段通过 JVM 内部的类加载机制,将 Class 对象加载到内存中。在创建对象实例之前,JVM 会先检查 Class 对象是否在内存中存在,如果不存在,则加载 Class 对象,然后再创建对象实例,如果存在,则直接根据 Class 对象创建对象实例。JVM 中只有一个 Class 对象,但可以根据 Class 对象生成多个对象实例[1]。
那么,Class
对象包含哪些信息?
类属性信息,即 Field
类的构造方法的信息
类方法
正在运行的 Java 应用程序中的类的实例
反射的使用
关于反射的使用,网上有很多资料,我主要从获取 Class 对象方式以及通过获取到的Class
对象创建对象实例两个角度进行介绍。
获取 Class 对象的方式
方式一:通过
Class.forName
静态方法,输入类的全路径来获取 Class 对象
方式二:通过
.class
方法,该方法仅限于编译前已知类名
方式三:通过类实例的
getClass
通过 Class 对象创建对象实例的方式
方式一: 通过
Class
对象的newInstance()
方法, 只支持无参构造
方式二: 通过
Constructor
对象的newInstance()
方法,该方式支持有参构造
相关的实现我存放在我的GitHub上了,另外实现了简单的
获取
Class
对象的属性信息获取
Class
对象的方法的
实例,主要是基于了解该方法的使用,有兴趣的可以看一下。
开源应用
我是在学习 Flink 支持的数据类型时,了解到 Flink 数据类型的描述信息都是TypeInformation
,在查看相关代码实现的过程中看到反射,借此机会将相关的信息也在此进行一个记录。
Flink 中关于类型相关的实现位于
flink\flink-core\src\main\java\org\apache\flink\api\common\typeinfo\
目录下,以ValueTypeInfo
为例来,相关的类图如下:
其中,ValueTypeInfo
中构造函数的入参便是通过反射机制中的Class
对象。
参考资料
版权声明: 本文为 InfoQ 作者【正向成长】的原创文章。
原文链接:【http://xie.infoq.cn/article/0a79e10a45ed711ba1891ebf5】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论