




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本文格式为Word版,下载可任意编辑——深入理解java的反射深入理解java的反射
要想理解反射的原理,首先要了解什么是类型信息。Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI,它假定我们在编译时已经知道了全体的类型信息;另一种是反射机制,它允许我们在运行时察觉和使用类的信息。
1、Class对象
理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息。Class对象就是用来创造全体“常规”对象的,Java使用Class对象来执行RTTI,即使你正在执行的是类似类型转换这样的操作。
每个类都会产生一个对应的Class对象,也就是保存在.class文件。全体类都是在对其第一次使用时,动态加载到JVM的,当程序创造一个对类的静态成员的引用时,就会加载这个类。Class对象仅在需要的时候才会加载,static初始化是在类加载时举行的。
publicclassTestMainpublicstaticvoidmainString[]argsSystem.out.printlnXYZ.name;classXYZpublicstaticStringname=luoxn28;staticSystem.out.printlnxyz静态块;publicXYZSystem.out.printlnxyz构造了;
输出结果为:
类加载器首先会检查这个类的Class对象是否已被加载过,假设尚未加载,默认的类加载器就会根据类名查找对应的.class文件。
想在运行时使用类型信息,务必获取对象譬如类Base对象的Class对象的`引用,使用功能Class.forName“Base”可以实现该目的,或者使用base.class。留神,有一点很好玩,使用功能”.class”来创造Class对象的引用时,不会自动初始化该Class对象,使用forName会自动初始化该Class对象。为了使用类而做的打定工作一般有以下3个步骤:
加载:由类加载器完成,找到对应的字节码,创造一个Class对象
链接:验证类中的字节码,为静态域调配空间
初始化:假设该类有超类,那么对其初始化,执行静态初始化器和静态初始化块
publicclassBasestaticintnum=1;staticSystem.out.printlnBase+num;publicclassMainpublicstaticvoidmainString[]args//不会初始化静态块Classclazz1=Base.class;System.out.println;//会初始化Classclazz2=Class.forNamezzz.Base;
2、类型转换前先做检查
编译器将检查类型向下转型是否合法,假设不合法将抛出奇怪。向下转换类型前,可以使用instanceof判断。
classBaseclassDerivedextendsBasepublicclassMainpublicstaticvoidmainString[]argsBasebase=newDerived;ifbaseinstanceofDerived//这里可以向下转换了System.out.printlnok;elseSystem.out.printlnnotok;
3、反射:运行时类信息
假设不知道某个对象确实切类型,RTTI可以报告你,但是有一个前提:这个类型在编译时务必已知,这样才能使用RTTI来识别它。Class类与java.lang.reflect类库一起对反射举行了支持,该类库包含Field、Method和Constructor类,这些类的对象由JVM在启动时创造,用以表示未知类里对应的成员。这样的话就可以使用Contructor创造新的对象,用get和set方法获取和修改类中与Field对象关联的字段,用invoke方法调用与Method对象关联的方法。另外,还可以调用getFields、getMethods和getConstructors等大量便利的方法,以返回表示字段、方法、以及构造器对象的数组,这样,对象信息可以在运行时被完全确定下来,而在编译时不需要知道关于类的任何事情。
反射机制并没有什么神秘之处,当通过反射与一个未知类型的对象打交道时,JVM只是简朴地检查这个对象,看它属于哪个特定的类。因此,那个类的.class对于JVM来说务必是可获取的,要么在本地机器上,要么从网络获取。所以对于RTTI和反射之间的真正识别只在于:
RTTI,编译器在编译时开启和检查.class文件
反射,运行时开启和检查.class文件
publicclassPersonimplementsSerializableprivateStringname;privateintage;//get/set方法publicstaticvoidmainString[]argsPersonperson=newPersonluoxn28,23;Classclazz=person.getClass;Field[]fields=clazz.getDeclaredFields;forFieldfield:fieldsStringkey=field.getName;PropertyDescriptordescriptor=newPropertyDescriptorkey,clazz;Methodmethod=descriptor.getReadMethod;Objectvalue=method.invokeperson;System.out.printlnkey+:+value;
以上通过getReadMethod方法调用类的get函数,可以通过getWriteMethod方法来调用类的set方法。通常来说,我们不需要使用反射工具,但是它们在创造动态代码会更有用,反射在Java中用来支持其他特性的,例如对象的序列化和JavaBean等。
4、动态代理
代理模式是为了供给额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色。Java的动态代理比代理的思想更前进了一步,它可以动态地创造并代理并动态地处理对所代理方法的调用。在动态代理上所做的全体调用都会被重定向到单一的调用处理器上,它的工作是透露调用的类型并确定相应的策略。以下是一个动态代理例如:
接口和实现类:
publicinterfaceInterfacevoiddoSomething;voidsomethingElseStringarg;publicclassRealObjectimplementsInterfacepublicvoiddoSomethingSystem.out.printlndoSomething.;publicvoidsomethingElseStringargSystem.out.printlnsomethingElse+arg;
动态代理对象处理器:
publicclassDynamicProxyHandlerimplementsInvocationHandlerprivateObjectproxyed;publicDynamicProxyHandlerOxyed=proxyed;@OverridepublicObjectinvokeObjectproxy,Methodmethod,Object[]argsthrowsIllegalAccessException,IllegalArgumentException,InvocationTargetExceptionSystem.out.println代理工作了.;returnmethod.invokeproxyed,args;
测试类:
publicclassMainpublicstaticvoidmainString[]argsRealObjectreal=newRealObject;Interfaceproxy=InterfaceProxy.newProxyInstanceInterface.class.getClassLoader,newClass[]Interface.class,newDynamicProxyHandlerreal;proxy.doSomething;proxy.somethingElseluoxn28;
输出结果如下:
通过调用Proxy静态方法Proxy.newProxyInstance可以创造动态代理,这个方法需要得到一个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 肉鸡养殖购销合同样本
- 建筑外墙清洗服务合同范本
- 合同终止通知书模板与合同范本
- 工程技术人才劳动合同书
- 应收账款质押贷款合同
- 机动车维修服务合同标准范本
- 劳动合同简化版合同模板
- 个人贷款合同还款计划书范本大全
- 简版个人商业空间租赁合同
- 集中隔离观察点培训课件
- 后循环缺血治疗
- 体育学科核心素养解析
- 2024年浙江绍兴杭绍临空示范区开发集团有限公司招聘笔试真题
- 2025年体检科医疗质量控制工作计划
- 2024年萍乡卫生职业学院单招职业适应性测试题库参考答案
- 飞行器小学生课件
- 无人机法律法规与安全飞行 第2版2-2 领空
- 《单片机应用实训教程》课件第4章
- 应急突发处置
- 2024年定融认购协议合同范文
- 系统思维与系统决策:系统动力学(中央财经大学)知到智慧树章节答案
评论
0/150
提交评论