《java概述课件24反射》由会员分享,可在线阅读,更多相关《java概述课件24反射(48页珍藏版)》请在金锄头文库上搜索。
1、类型信息与反射1.类型信息存储2.类型信息概述3类型信息的加载4核心类介绍5Class类的获取方法6获取Construction方法7获取Method对象8获取Field对象9类型信息运用RTTI类型信息存储编译java类文件Java编译器存储在.class文件中文本文件翻译成二进制的字节码1class文件与java文件类型信息概述.java文件中只含有一个类或接口只产生一个.class文件publicclassPerson字节码存放在Person.class文件中java类文件中存在内部类产生多个.class文件publicclassPersonclassToolinterfaceCommu
2、nicationpublicvoidspeak();文件名都以外部类名+$+内部类名来命名Person.class、Person$Tool.class、Person$Communication.class.java文件中存在多个并行类(或接口)会产生多个.class文件publicclassPersonclassMonkeyinterfaceThinkingvoidthink();Person.class、Monkey.class、Thinking.class类型信息概述java类文件中的属性、方法、以及类中的常量信息都被分别存储在.class文件中。参考:2Class的文件结构长度:4字节描
3、述:魔数OxCAFEBABE备注:Od-X命令可以看到。这样保证了java虚拟机能很轻松的分辨出java文件和非java文件。长度:分别两字节描述:主次版本号class文件备注:格式一旦发生变化,版本也会随之变化。如果class文件版本号超出了处理范围,java文件将不会处理文件。长度:不固定描述:包含了文件中类和接口相关的常量。文字字符串、final变量值、类名和方法名的常量。常量池的大小平均占到了整个类大小的60%左右。长度:2字节描述:访问标志:定义了类或接口备注:指明是类还是接口、是抽象还是具体。长度:两字节描述:本身是一个常量池的索引,指向了常量池中该类全限定名的常量池入口。长度:2
4、字节描述:指向父类全限定名长度:不固定描述:属性总数和属性本身长度:不固定描述:方法总数和方法本身长度:不固定描述:字段数量和字段的信息表。描述了字段的类型和描述符等。长度:不固定描述:该类实现的接口数量,interfaces包含了由该类实现的接口的常量池应用。java编译一个类文件翻译类文件为该类动态的添加一个公有的静态常量属性.class这个属性记录了类的相关信息,即类型信息,它是Class类的一个实例。类型信息概述类型信息的加载JAVA提供两种类的装载方式:一是预先装载,二是按需装载。由于可以对类进行按需加载,因此在程序启动时并不需要把所有类都装载到JVM中。大部分的类要被延迟到使用时才
5、动态加载,这称为JAVA的运行时动态装载机制。 JAVA基础类的加载当启动一个程序时,JAVA首先在JDK目录找到并载入,然后启动虚拟机。启动虚拟机时会做一些初始化操作,如设置系统参数等。接着会创建一个BootstrapLoader对象称为启动类装载器。含有main()函数类的加载拥有mian()函数的入口类即由AppClassLoader在程序启动时加载。Bootstrap LoaderExtClassLoaderAppClassLoader1、预先加载运行结果:JAVA采用运行时动态装载机制,需要某个类时,JVM才会去动态的装载它装载条件在程序的运行过程中,一个类的静态成员(静态方法、静态
6、属性、构造方法)被第一次引用时,JVM就会去装载它。要注意的是:当访问静态常量属性时,JVM加载类的过程中不会进行类的初始化工作。构造方法作为类的静态成员的特例,既,当使用new关键字来构造一个对象时,会被当作类静态成员的引用,同样会触发JVM来加载这个类。2、按需加载例如:输出结果:按需加载流程图是用原生代码来实现的。它负责将/lib下面的类库加载到内存中。不允许直接通过引用进行操作引导类(Bootstrap)加载器是由Sun的AppClassLoader实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。系统类(System)加载器是由
7、Sun的ExtClassLoader实现的。它负责将/lib/ext或者由系统变量java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用扩展类加载器。扩展类(Extension)加载器3、JVM三种预定义类型类加载器除引导类加载器,所有的类加载器都有一个父类加载器,并且,所有的类加载器都是类型。某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。参考:4、加载器的工作运行结果:当一个类具有继承关当一个类具有继承关系时,装载时从顶级系时,装载时从顶级类开
8、始的,依次类推类开始的,依次类推直至加载到这个类本直至加载到这个类本身身5、父类和子类的加载顺序未初始化的静态引用publicclassCoursestaticSystem.out.println(Courseprepare!);publicclassTeacherstaticSystem.out.println(Teacherprepare!);publicstaticCoursecourse;publicclassBootstrappublicstaticvoidmain(Stringargs)newTeacher();初始化后:把Teacher类中的publicstaticCoursec
9、ourse;改为publicstaticCoursecourse=newCourse();对course进行初始化,改后的运行结果:运行结果:运行结果:Teacher prepare!运行结果:运行结果:Teacher prepare!Course prepare!6类型信息的表示类型信息概述7类型信息的表示核心类介绍1Class类Class类的对象用来表示运行时类或接口的信息。比如:每个数组均属于一个Class类对象,所有具有相同元素类型和维数的数组共享一个Class对象。基本的Java类型(boolean,byte,char,short等)和void类型也可表示为Class对象。Class
10、对象是类型信息的核心,它直接对类的整体进行描述。我们自己无法生成一个Class对象(构造函数为private),而这个Class类的对象是在当各类被调入时,由Java虚拟机自动创建Class对象,或通过类装载器中的defineClass方法生成Class类的获取方法1通过.class属性Class类的获取方法这个方法是用来取得该类已经被实例化了的对象的该类的引用,这个引用指向的是Class类的对象。2、通过getClass()方法Class类的获取方法该方法返回给定串名相应的Class对象。若给定一个类或接口的完整路径名,那么此方法将试图定位、装载和连接该类。若成功,返回该类对象。否则,抛出C
11、lassNotFoundException异常。2、通过forName()方法输出结果:核心类介绍专门用来描述构造函数,即Constructor类。Constructor类的对象用于描述类的单个构造方法。可以通过它来获取类的构造方法名称、访问权限等,甚至可以用Constructor来构建类的实例。2、获取Constructor对象对于这四个不同的构造方法就会有4个不同的Constructor对象来描述。获取Construction方法1、getConstructor(ClassparameterTypes)此方法用于获取指定参数类型的Constructor对象,其中参数parameterTyp
12、es为指定的参数类型。获取的构造方法必须是公有的。输出结果:获取Construction方法2、getConstructors()此方法用于获取指定类的公有构造函数描述对象Constructor列表。如果指定类没有公有的构造函数,则返回一个长度为0的Constructor数组输出结果:获取Construction方法3、getDeclaredConstructor(ClassparameterTypes)此方法也是用于获取指定参数类型的构造函数描述对象Constructor,与getCon-structor(ClassparameterTypes)不同的是,该方法除了可以获取公有的构造函数描述
13、对象外,还可以获取用于描述受保护的或私有的构造函数的Constructor对象。输出结果:获取Construction方法4、getDeclaredConstructors()此方法用于获取指定类的所有构造函数描述对象列表。与getConstructors()方法不同的是,它除了可以获取公有的构造方法描述对象外,还可以获取私有的构造方法描述对象。输出结果:。获取Method对象1、native方法一个NativeMethod就是一个java调用非java代码的接口。在定义一个nativemethod时,并不提供实现体(有些像定义一个javainterface),因为其实现体是由非java语言在
14、外面实现的。核心类介绍3、获取Method对象Method类的对象用于描述类的单个方法(不包括构造方法)。可以通过Method类来获取方法的访问权限、参数类型、返回值类型等信息。并且可以通过获取的Method对象来动态执行方法。获取Method对象2、getMethod(Stringname,ClassparameterTypes)此方法用于获取指定名称和参数类型的公有方法描述对象。可获取的方法出了本身定义的方法外,还包含了继承自父类的方法。由于java支持方法多态,因此会出现同名方法,所以获取一个方法描述对象时,必须同时指明方法名称和参数类型。如果没有参数可不设置。获取Method对象2、g
15、etMethod(Stringname,ClassparameterTypes)输出结果:获取Method对象3、getMethods()方法用于获取公有的方法描述对象列表。获取的列表中,不仅包括本身类定义的方法描述对象,还包含继承自父类或接口的方法描述对象获取Method对象3、getMethods()输出结果:获取Method对象4、getDeclaredMethod(Stringname,ClassparameterTypes)此方法也用于获取指定名称和参数类型的方法描述对象。与方法getMethod(Stringname,Class.parameterTypes)不同的是,此方法可以获
16、取非公有的方法描述对象。获取Method对象5、getDeclaredMethods()此方法用于获取类本身定义的所有方法描述对象。注:获取的方法描述对象不包括继承自父类或接口的方法描述对象。此方法与getMethods不同的是,它只可以获取类本身定义的方法描述对象,而且获取的包括公有的、受保护的以及私有的方法描述对象。获取Field对象获取field对象Field类的对象用于描述类的单个字段。可以通过对Field对象来获取字段的访问权限、字段类型等信息。并且可以通过获取的Field对象来动态的修改字段值。获取Filed对象Field的获取方法publicFieldgetField(Strin
17、gname)返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段publicFieldgetFields()返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段publicFieldgetDeclaredField(Stringname)返回一个Field对象,该对象反映此Class对象所表示的类或接口的指定已声明字段publicFieldgetDeclaredFields()返回一个Field的数组,该数组记录指定类的所有属性的描述对象。如果指定类没有属性,则返回一个空数组类型信息运用RTTIRTTI简介简介RTT
18、I:RunTimeTypeIdentification,运行时类型识别在程序运行时,动态的识别对象和类的信息如:公司发放奖金时不同职位的人获得的奖金不同,就需识别他们的职位类型信息运用RTTI怎样进行运行时类型识别关键字instanceof语法如下:employeeinstanceofEmployee。这样的一个表达式返回一个boolean值,若为true,则表示是指定类的一个实例,若返回false,则表示不是指定类的实例。例如:If(xinstanceofDog)(Dog)x.bark();Class.isInstance()原型:publicbooleanisInstance(Object
19、obj)参数是一个类的实例,对象contents1类型信息应用2.动态代理3动态代理类4动态代理实例5.被代理的接口6动态代理的不足类型信息应用JAVA反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,修改它的任意属性;这种动态获取的信息以及动态调用对象成员的功能称为java语言的反射机制。反射类型信息应用Java反射机制提供的功能:用于reflection的类,如Method,可以在java.lang.relfect包中找到。使用这些类的时候必须要遵循三个步骤:类型信息应用在程序运行的过程中,我们获取到了一个字符串,并且
20、被告知这串字符串表示一个类,而且这个类继承了抽象的Person类。例子:显示加载类:实例class提供了forName(Stringname)方法来显示加载类运行结果:类型信息应用1.Class类的newInstance()方法该方法用于创建指定类的实例对象。例子:通过反射实例化类运行结果:类型信息应用Constructor类的newInstance()方法newInstance(ClassannotationClass),该方法用于使用指定参数类型的构造函数描述对象实例化一个类。例子:通过反射实例化类运行结果:类型信息应用Method类拥有invoke(Objectobj,Object.ar
21、gs),该方法可以让我们执行指定对象的方法。该方法拥有两个参数,一个是指定的对象,表示在哪个对象上执行该方法,另二个是参数,即执行方法需要传入的参数。例子:运行结果:通过反射执行方法类型信息与反射Field有一方法set(Objectobj,Objectvalue),用于动态的给属性赋值。这个方法有两个参数,第一个参数表示要修改属性的对象,第二个参数表示修改后的值。例子:运行结果:通过反射修改属性类型信息与反射FieldField、MethodMethod以及ConstructorConstructor的父类AccessibleObject提供一个方法:setAccessiblesetAccessible(booleanflag)(booleanflag),该方法用于设置访问对象的accessibleaccessible标志, ,当该标志为truetrue时,反射的对象在使用时取消javajava语言访问检查,此时我们就可顺利使用反射对象了修改访问权限由于Method类也继承了AccessibleObject,因此通过反射调用对象非公有的方法,也需要设置accessible标志。