《第8章Java的反射机制.ppt》由会员分享,可在线阅读,更多相关《第8章Java的反射机制.ppt(38页珍藏版)》请在优知文库上搜索。
1、Java的反射机制主要内容1.Class的基本概念以及创建方式的基本概念以及创建方式2.反射的基本概念反射的基本概念3.类的各个组成部分对应的反射类类的各个组成部分对应的反射类 Constructor Field Method4.反射在框架中的应用反射在框架中的应用反射的基础-ClassJava当中的类用来表示具有相同属性和方法的对象的结合,是当中的类用来表示具有相同属性和方法的对象的结合,是抽象的概念。对象是类创建的,同一个类的不同对象具有不抽象的概念。对象是类创建的,同一个类的不同对象具有不同的属性值。同的属性值。Java当中定义的所有类都属于同一类事物,可以用当中定义的所有类都属于同一类
2、事物,可以用Class来表来表示。示。对比理解:对比理解:不同的人可以用不同的人可以用Person类来表示。类来表示。人人-Person Java当中定义的不同类可以用当中定义的不同类可以用Class来表示。来表示。Java当中的类当中的类-ClassClass类的对象-字节码Class类的对象就是不同的类对应的字节码。类的对象就是不同的类对应的字节码。获取获取Class的对象的对象Person p1=new Person();Class class1=new Class()()三种方式:三种方式:(1)对象名对象名.getClass()Person p1=new Person();p1.ge
3、tClass();(2)类名类名.class Date.class(3)Class.forName()方法方法 (此方式用的较多此方式用的较多)Class.forName(“java.lang.String”);基本数据类型的Class对象Java当中的基本数据类型有:当中的基本数据类型有:boolean int short byte char long float 和和 double 它们也有各自的它们也有各自的Class对象。对象。例如:例如:int.class void 也有自己对应的也有自己对应的Class对象对象 void.class 基本数据类型对应的封装类有属性基本数据类型对应的
4、封装类有属性TYPETYPE,这个属性,这个属性代表了封装类所封装的基本数据类型的代表了封装类所封装的基本数据类型的ClassClass对象。对象。int.class=Integer.TYPEint.class=Integer.TYPE void.class=Void.TYPE void.class=Void.TYPE反射(Reflect)反射就是把反射就是把JavaJava类中的各个组成部分映射成相应的类中的各个组成部分映射成相应的JavaJava类。类。一个类的组成部分包括:属性、方法、构造方法、包等。这些一个类的组成部分包括:属性、方法、构造方法、包等。这些组成部分都会被映射成相应的类。
5、组成部分都会被映射成相应的类。Class类定义了一系列方法来获取类定义了一系列方法来获取java类的属性、方法、构造方类的属性、方法、构造方法、包等信息,这些信息都有相应的类来表示,分别是法、包等信息,这些信息都有相应的类来表示,分别是Field、Method、Constructor、Package等。等。注意:表示注意:表示javajava类组成部分的各种类位于类组成部分的各种类位于java.lang.reflectjava.lang.reflect包包中。中。Constructor类Constructor类用来描述类中所定义的构造方法。类用来描述类中所定义的构造方法。(1)得到类的所有构造
6、方法得到类的所有构造方法 Constructor constructors=Class.forName(“java.lang.String”).getConstructors();(2)得到类中某个具体的构造方法得到类中某个具体的构造方法,在在getConstructor中传入参数类型所对应的中传入参数类型所对应的字节码字节码 Constructor constructor=Class.forName(“java.lang.String”).getConstructor(String.class)使用使用Constructor类的目的是用来创建相应类的对象类的目的是用来创建相应类的对象 正常情
7、况正常情况 String str=new String(“hello”);反射情况反射情况 Constructor con=String.class.getConstructor(String.class)String str=(String)con.newInstance(“hello”);Class.newInstance()通过反射方式创建对象的过程通过反射方式创建对象的过程 Class-Constructor-某个类的对象某个类的对象只有当要只有当要用某个类的无参构造方法创建该类对象时用某个类的无参构造方法创建该类对象时,可以,可以省略创建省略创建ConstructorConstruc
8、tor类对象的这个过程。类对象的这个过程。Date d=(Date)Class.forName(“java.util.Date”).newInstance();注意:注意:javajava运行环境的缓存中保存了类的无参构造方法所对应运行环境的缓存中保存了类的无参构造方法所对应的的ConstrutorConstrutor对象。对象。见源文件:见源文件:ReflectTest.javaReflectTest.javaField类 Field类用来表示类中的属性类用来表示类中的属性(字段字段)。(1)Class.getFields():(1)Class.getFields():得到得到ClassCl
9、ass对象的所有字段,返回的是对象的所有字段,返回的是FieldField数组。数组。(2)Class.getField(String name)(2)Class.getField(String name)返回一个返回一个 Field Field 对象,它反映此对象,它反映此 Class Class 对象所表示的类或接口的指定对象所表示的类或接口的指定公有成员公有成员字段。字段。(3)Field(3)Field的对象所代表的某一个类的属性,而的对象所代表的某一个类的属性,而不是那个类的某一个对象的属不是那个类的某一个对象的属性性。要得到某个对象对应的属性值,需要通过。要得到某个对象对应的属性值
10、,需要通过get(Object obj)get(Object obj)方法与某个方法与某个对象具体关联。对象具体关联。(4)(4)对于对于非公有属性非公有属性只能通过只能通过ClassClass的的getDeclaredField(String fieldName)getDeclaredField(String fieldName)方法得到。方法得到。(5)(5)对于对于私有属性私有属性要得到它所关联到的对象的值,需通过要得到它所关联到的对象的值,需通过FieldField的的setAccessible(boolean boolean)setAccessible(boolean boolean
11、)方法设置。方法设置。(6)Field(6)Field类的类的getType()getType()方法用来得到字段所属的类型方法用来得到字段所属的类型 见源文件:见源文件:Field/FieldTest.javaField类 练习:扫描一个对象中所有的字符串类型的练习:扫描一个对象中所有的字符串类型的属性,并为每一个字符串属性的值后面添加属性,并为每一个字符串属性的值后面添加“hello”字符串,然后将这个对象输出。字符串,然后将这个对象输出。见源文件:见源文件:Field/FieldTest1.java 注意:对于字节码的比较一定要用注意:对于字节码的比较一定要用“=”=”,而不是,而不是e
12、quals()equals()。掌握上述例子对于理解掌握上述例子对于理解SpringSpring等框架技术具有重要作用。等框架技术具有重要作用。Method类 Method用来表示类中的方法。通过用来表示类中的方法。通过Class对象的如下对象的如下方法得到方法得到Method对象对象Method getMethod(String name,Class.parameterTypes)按名称得到某个特定的按名称得到某个特定的public方法方法(包括从父类或接口继承的方法包括从父类或接口继承的方法)Method getMethods()得到得到public方法方法(包括从父类或接口继承的方法包括
13、从父类或接口继承的方法)Method getDeclaredMethods()得到所有的方法得到所有的方法(不包括继承的方法不包括继承的方法)Method getDeclaredMethod(String name,Class.parameterTypes)按名称得到某个特定的方法按名称得到某个特定的方法(不包括继承的方法不包括继承的方法)Method类Class的的getMethod()方法得到方法得到Method类的对象。类的对象。(1)需要传递方法名所对应的字符串需要传递方法名所对应的字符串(2)需要传递该方法所需要的参数类型的字节码需要传递该方法所需要的参数类型的字节码 invoke(
14、Object obj,Object obj)方法用来调用方法用来调用Method所表示的方法。其中,第一个参数表示此方法所表示的方法。其中,第一个参数表示此方法作用于哪一个对象。作用于哪一个对象。见源文件:见源文件:Method/MethodTest.java 注意:如果调用的是个静态方法,那么注意:如果调用的是个静态方法,那么invoke()invoke()方法中第一个参数用方法中第一个参数用nullnull表示。表示。对接收数组参数的方法进行反射问题:编写一个程序,这个程序能够接收用户提供的类名,然问题:编写一个程序,这个程序能够接收用户提供的类名,然后去执行这个类中的后去执行这个类中的m
15、ain()方法。方法。见源文件:见源文件:method/MethodTest1.java注意:注意:JDK1.4JDK1.4的编译器会把数组中的每一个元素作为一个参数,的编译器会把数组中的每一个元素作为一个参数,来调用此接收数组参数的方法,这样的话就出现了参数不对来调用此接收数组参数的方法,这样的话就出现了参数不对应的问题。应的问题。mainMethod.invoke(null,new Stringaaa,bbb,ccc);JDK1.5JDK1.5为了兼容为了兼容1.41.4,就必须将整个数组作为一个只有一个元素,就必须将整个数组作为一个只有一个元素的的ObjectObject数组进行传递。数
16、组进行传递。以下两种方式正确:以下两种方式正确:(1)mainMethod.invoke(null,new Objectnew Stringaaa,bbb,ccc);(2)mainMethod.invoke(null,(Object)new Stringaaa,bbb,ccc);数组的反射在在Java中数组属于复合数据类型,中数组属于复合数据类型,具有相同元素类型和维数的具有相同元素类型和维数的数组属于同一个类型数组属于同一个类型,即具有相同的字节码对象。,即具有相同的字节码对象。代表数组的字节码对象调用代表数组的字节码对象调用getSuperClass()得到它的父类得到它的父类Object的字节码对象。的字节码对象。基本数据类型的一维数组可以当做基本数据类型的一维数组可以当做Object类型使用,但类型使用,但不能当不能当做做Object类型使用类型使用;基本数据类型的二维数组可以当做;基本数据类型的二维数组可以当做Object类型使用;类型使用;复合数据类型的一维数组既可以当做复合数据类型的一维数组既可以当做Object类型使用,也可以当做类型使用,也可以当做Object类型使用