Java高级进阶-反射

前言

反射是高级框架的基础,是进阶必备知识点之一,今天就来总结一下反射前前后后相关的知识点。

1.反射机制介绍

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

简单的说就是,一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

2.反射作用

反射可以让我们在运行时获取类的属性,方法,构造方法、父类、接口等信息,通过反射还可以让我们在运行期实例化对象、调用方法、及时方法或属性是私有的也可以通过反射的形式调用。

3.创建和使用

3.1  获取class字节码对象

1.使用Class类的forName(String clazzName)静态方法。该方法需要传入字符串参数,该字符串参数的值是某个类的全限定名(必须添加完整包名)。

2.调用某个类的class属性来获取该类对应的Class对象。

3.调用某个对象的getClass()方法。该方法是java.lang.Object类中的一个方法。


方法1:Class clazz = Class.forName("com.reflect.Student");

方法2Class clazz1 = Student.class;

方法3:Student student = new Student();Class clazz2 = student.getClass();


3.2.获取class对象的属性、构造方法、普通方法

3.2.1  获取class对象的属性


Field[] allFields = clazz.getDeclaredFields();//获取class对象的所有属性

Field[] publicFields = clazz.getFields();//获取class对象的public属性

Field ageField = clazz.getDeclaredField("name");//获取class指定属性

Field desField = clazz.getField("age");//获取class指定的public属性


3.2.2  获取class对象的构造方法


Constructor[] allConstructors = clazz.getDeclaredConstructors();

//获取class对象的所有声明构造函数

Constructor[] publicConstructors = clazz.getConstructors();

//获取class对象public构造函数

Constructor constructor = clazz.getDeclaredConstructor(String.class);

//获取指定声明构造函数

Constructor publicConstructor = clazz.getConstructor(String.class);

//获取指定声明的public构造函数


3.2.3  获取class对象的普通方法


Method[] methods = clazz.getDeclaredMethods();//获取class对象的所有声明方法

Method[] allMethods = clazz.getMethods();//获取class对象的所有public方法 包括父类的方法

Method method = clazz.getMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的public方法

Method declaredMethod = class1.getDeclaredMethod("info", String.class);//返回次Class对象对应类的、带指定形参列表的方法


3.2.4  获取class对象的信息


boolean isPrimitive = class1.isPrimitive();//判断是否是基础类型

boolean isArray = class1.isArray();//判断是否是集合类

boolean isAnnotation = class1.isAnnotation();//判断是否是注解类

boolean isInterface = class1.isInterface();//判断是否是接口类

boolean isEnum = class1.isEnum();//判断是否是枚举类

boolean isAnonymousClass = class1.isAnonymousClass();//判断是否是匿名内部类

boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);//判断是否被某个注解类修饰

String className = class1.getName();//获取class名字 包含包名路径

Package aPackage = class1.getPackage();//获取class的包信息

String simpleName = class1.getSimpleName();//获取class类名

int modifiers = class1.getModifiers();//获取class访问权限

Class[] declaredClasses = class1.getDeclaredClasses();//内部类

Class declaringClass = class1.getDeclaringClass();//外部类


3.3  使用class对象

3.3.1  实例操作class对象方法

1.首先根据获取的class对象获取对应的Method方法集合或者获取指定方法

2.通过method方法对象调用invoke(Object obj,Object...params)方法来进行对对象进行修改赋值操作等等。第一个参数是传入的class对象,第二个是对应方法的参数列表。


// 生成新的对象:用newInstance()方法

Object obj = class1.newInstance();

//首先需要获得与该方法对应的Method对象

Method method = clazz.getDeclaredMethod("setAge", int.class);

//调用指定的函数并传递参数

method.invoke(obj, 28);


3.3.2  实例化操作class对象属性

1.通过Class对象的getFields()方法或者getField()方法获得指定方法,返回Field数组或对象。

2.Field提供了两组方法来读取或设置成员变量的值:

getXXX(Object obj):获取obj对象的该成员变量的值。此处的XXX对应8种基本类型。如果该成员变量的类型是引用类型,则取消get后面的XXX。

setXXX(Object obj,XXX val):将obj对象的该成员变量设置成val值。


//生成新的对象:用newInstance()方法

Object obj = class1.newInstance();

//获取age成员变量

Field field = class1.getField("age");

//将obj对象的age的值设置为10

field.setInt(obj, 10);

//获取obj对象的age的值

field.getInt(obj);


3.4  访问权限

在操作class对象方法时,会遇到无法访问的问题,这是因为,方法的访问权限为private,这时我们需要主动将访问权限修改,通过调用method对象的setAccessible(true)可以解决问题。

总结

反射机制是框架的支撑,在Java中有一套获取所有类字节码对象的API,而这正好为我们间接的操作对象提供了方便,同时反射降低了类与类的依赖性,不需要导包,即可创建对象。

参考:

http://www.jianshu.com/p/779b3e27b26d

http://www.jianshu.com/p/f67182a482eb

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

推荐阅读更多精彩内容