【修真院java小课堂】Java反射机制简单介绍

大家好,我是来自北京分院的第32期java学员,今天我要给大家简要介绍下Java中的反射机制

1、背景介绍(摘自wiki):

物理学概念:反射是两个不同介质之间的界面处波前方向的变化,使得波前返回到其起源的介质中。

计算机科学概念:反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。

2、知识剖析:

2.0 类加载机制

源代码编译为字节码文件,字节码文件能通过类加载器加载到jvm分配的内存中(即加载类),然后jvm会根据加载的信息生成一个java.lang.Class类的实例即Class对象,此Class对象跟刚刚加载的类是对应的,Class对象记录着对应类的信息,包括成员变量、方法、构造器、内部类等等,通过此Class对象能够访问并修改对应类的信息(Class类提供了各种各样的方法来实现)

2.1 如何获取Class对象

•使用 Class 类的forName(String className)静态方法,此方法需要传入字符串参数,该字符串参数的值是某个类的全限定类名(必须添加完整包名)。
•调用某个对象的class属性来获取该类对应的Class对象,如Person.class将会返回Person类对应的Class对象。(Java编程思想里称类字面常量)
•调用某个对象的getClass()方法,该方法是java.lang.Object类中的一个方法,所有Java对象都可以调用该方法,该方法将会返回该对象所属类对应的Class对象。

2.1.1从Class中获取信息

class类提供了大量的实例方法来获取该Class对象所对应类的详细信息(构造器、方法、成员变量、内部类、注解等),具体方法看api
通过Class对象可以得到大量的Method、Constructor、Field等对象,这些对象分别代表该类所包括的方法、构造器和成员变量等,程序可以通过这些对象来执行实际的功能,例如调用方法、创建实例。

2.2 使用反射生成并操作对象

2.2.1 创建对象(两种方式)

    (1)使用Class对象的newInstance()方法来创建该Class对象对应类的实例,此方式要求该Class对象的对应类有默认构造器,而执行 newInstance() 方法时实际上是利用默认构造器来创建该类的实例。
    (2)先使用Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例。通过这种方式可以选择使用指定的构造器来创建实例。

        通过第一种方式来创建对象是比较常见情形,因为在很多JavaEE框架中都需要根据配置文件信息来创建Java对象,从配置文件中读取的只是某个类的字符串类名,程序需要根据该字符串来创建对应的实例,就必须使用反射。

          使用配置文件来创建对象-spring(xml配置文件)

2.2.2 调用方法

当获得某个类对应的Class对象后,就可以通过该Class对象的getMethods()方法或者getMethod()方法来获取全部方法或指定方法,这两个方法的返回值是Method数组或者是Method对象。
Method类中常用方法:Object invoke(Object obj, Object...args)

2.2.3 访问成员变量

 主要通过Class对象的 getFields()或 getField() 方法可以获取该类所包含的全部成员变量或指定成员变量。

2.2.4 操作数组

在java.lang.reflect包下还提供了一个Array类,Array对象可以代表所有的数组,程序可以通过使用Arragy来动态的创建数组,操作数组元素等。

3.常见问题

(1)反射是为了解决什么问题
Java中,在运行时识别对象和类的信息的方式还有一种,称为RTTI(Run-Time Type Identification:运行时类型信息),使用它有个前提,即所查询的类或对象的类型必须在编译时已知。换句话说,对于RTTI,编译器在编译时打开和检查.class文件
如果.class文件在编译时不可获取,那么怎么在运行时打开和检查.class文件呢?于是反射机制就出现了,使用反射不需要前提条件,只要类被加载进虚拟机,通过反射就能获取到该类信息。设计到rmi

(2)既然已经知道了这个类的类名,为何不直接new他的对象,而要用反射实现,不是多此一举吗?使用反射有什么好处

反射机制对于开发web的普通开发者来说用的不多,它的主要用处是用于框架的开发,例如大名鼎鼎的spring,它的控制反转及依赖注入就是依靠反射来实现的。使用反射主要是它能通过类名来进行实例化,而类名的信息是可以通过配置文件来保存的,所以可以通过修改配置文件来取得自己想要的对象。

(3)利用反射能访问私有成员变量吗?

   答案是肯定的,方法中带有Declare的是可以访问所有信息的,例如getDeclaredField() 方法则可以获取所有的成员变量,包括用private修饰的私有成员变量。

 

参考资料:

维基百科

《Java编程思想》第四版

《疯狂Java讲义》(注:大部分内容摘于此书,此书浅析易懂,适合初学者)

 

今天的分享就到这了,希望大家多多指正,互相学习~

技能树.IT修真院 “我们相信人人都可以成为工程师,从现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫。” 这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄一对一可见指导。

快来与我一起学习吧http://www.jnshu.com/login/1/21816764 (使用21816764邀请码有惊喜)

还有最帅的老大哦~

猜你喜欢

转载自blog.csdn.net/itleo1122/article/details/81262867