反射

1.1    Java反射概述

反射(Reflection)机制是Java语言特性之一,是Java被视为动态(或准动态)语言的一个关键特性。

1.1.1    什么是反射

在计算机领域,反射指一种能力,能够自描述和自控制,即在运行状态中,动态获取类信息及动态调用实例方法的能力。

Java反射有以下3个动态特性。

▶    运行时创建实例。

▶    运行期间调用方法。

▶    运行时更改属性。

如何理解Java的反射机制呢?首先来回顾一下Java程序的执行过程。Java程序要想运行,Java类必须被Java虚拟机加载。

之前我们所运行的程序都是在编译时就已经链接了所有所需的类,而Java反射机制则允许程序在运行时再加载、探知、使用那些在编译时完全未知的类。例如,在之前课程中使用JDBC时,使用Class.forName()方法通过一个字符串形式的类名查找并加载驱动类,就是对反射机制的初步运用。每个项目中使用的数据库产品和版本都不是一成不变的,在代码中用new关键字实例化驱动类的传统做法是不明智的,而利用反射机制则可以在运行时读取配置文件中的驱动类名,动态加载所需的驱动类。

反射机制允许Java程序加载一个运行时才得知其名称的类,获悉其完整API信息,包括其修饰符(诸如public、static等)、超类、实现的接口,也包括属性和方法的所有信息;并可生成其实例、对其属性赋值或调用其方法。通过Java反射可以实现以下功能。

▶    在运行时探知任意一个实例所属的类。

▶    在运行时构造任意一个类的实例。

▶    在运行时探知任意一个类所具有的方法和属性。

▶    在运行时调用任意一个实例的方法。

就像照镜子能够看清自己,反射使程序可以看清一个类的情况并加以使用。Java反射机制能够探知类的基本结构,这种对Java类结构探知的能力,称为Java类的“自审”。并且,反射机制是构建框架技术的基础所在,掌握Java反射机制,对以后学习框架技术有很大的帮助。

1.1.2    Java反射常用API

使用Java反射技术,常用的类如下。

▶    java.lang.Class<T>类:反射的核心类,反射所有的操作都是围绕该类来生成的。通过Class类可以获取类的属性、方法等内容信息。

▶    java.lang.reflect.Constructor<T>类:表示类的构造方法。

▶    java.lang.reflect.Field类:表示类的属性,可以获取和设置类中属性的值。

▶    java.lang.reflect.Method类:表示类的方法,可以用来获取类中方法的信息或执行方法。

1.2    反射的的应用

在Java程序中使用反射的基本步骤如下。

(1)导入java.lang.reflect包中的相关类。

(2)获得需要操作的类的Class实例。

(3)调用Class实例的方法获取Field、Method等实例。

(4)使用反射API操作实例成员。

1.2.1    获取类的信息

1.    获取Class实例

▶    调用类或接口实例的getClass()方法。

Class clz = obj.getClass(); // obj为某个类型的实例

▶    调用类或接口的class属性。

Class clz = Student.class; // Student 为自定义的学生类型

▶    使用Class.forName()方法。

Class clz = Class.forName("com.mysql.cj.jdbc.Driver");

2.    从Class实例获取信息

在获得了某个类型对应的Class实例之后,就可以调用Class实例的方法来获得该类型的信息。Class类提供了大量实例方法来获取对应类型的详细信息。

▶    获取对应类型的基本信息,相关方法:获取对应类型的基本信息的方法:方法名:String getName(),说明:以字符串形式返回该类型的名称。方法名:String getSimpleName(),说明:以字符串形式返回该类型的简称。方法名:Package getPackage(),说明:获取该类型所在的包。方法名:Class getSuperclass(),说明:返回该类型的超类的Class实例。方法名:Class[] getInterfaces(),说明:返回该类型所实现的全部接口的Class实例。方法名:int getModifiers(),说明:返回该类型的所有修饰符,由public、protected、private、final、static、abstract等对应的int常量组成,返回的整数应使用Modifier工具类来解码,才可以判断修饰符的构成。方法名:Class[] getDeclaredClasses(),说明:返回该类型中包含的全部内部类的Class实例,方法名:Class getDeclaringClass(),说明:返回该类型所在的外部类的Class实例。

1.2.2    创建实例

通过反射来创建Java类型的实例有如下两种方式。

▶    使用Class实例的newInstance()方法创建相关类型的实例。

▶    使用Constructor实例创建相关类型的实例。

1.2.3    访问类的属性

使用Field实例可以对属性进行取值或赋值操作,主要方法:访问属性的方法:方法:xxx getXxx(Object obj),说明:xxx表示8种基本数据类型之一,如int getInt(Object obj)。obj为该属性所在类的实例。假设instance表示A类的实例,field表示A类中的属性a,则field.getInt(instance)表示以int类型返回instance中属性a的值。若Field实例表示的是一个静态属性,则obj可以设置为null。方法:Object get(Object obj),说明:以Object类型返回obj中相关属性的值。方法:void setXxx(Object obj, xxx val),说明:将obj中相关属性的值设置为val。xxx为8种基本数据类型之一。方法:void set(Object obj,Object val),说明:将obj中相关属性的值设置为val。方法:void setAccessible(boolean flag),说明:对相关属性设置访问权限。设置为true可以禁止Java语言访问检查。

1.2.4    调用类的方法

Method类中包含一个invoke()方法,通过invoke()方法,Method实例可以调用Java类的实例方法和静态方法。invoke()方法定义如下:

                  Object invoke(Object obj, Object... args);

其中,obj是执行该方法的对象,args是执行该方法时传入的参数。

例如,method表示A类中的fun()方法,instance是A类的实例,则method.invoke(instance,args)表示调用instance的fun()方法并传入参数args。

若Method实例表示的是一个静态方法,则obj可以为null。

本章总结

◎    Java反射机制是指在运行状态中,动态获取类型信息及动态访问实例成员的能力。

◎    使用反射可以在程序运行时创建类的实例及访问其属性和方法。

◎    反射在Java框架技术中有着大量的应用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,701评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,649评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,037评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,994评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,018评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,796评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,481评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,370评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,868评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,014评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,153评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,832评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,494评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,039评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,437评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,131评论 2 356

推荐阅读更多精彩内容