一、反射的概念
反射的本质是将类中的感兴趣的成分映射成相应的类,接着通过这些类的实例访问原来类中的相应成分。
对于类中的不同成分,其由谁声明,就从谁的身上获得相应成分的类的对象;其由谁使用,就从谁身上访问该成分的值。
二、反射类的构造方法
1、通过.class或者类加载器获得类的Class对象。
2、通过这个对象的方法获得Construct类的一个实例。(注意:Class对象的方法都是以class类型(.class)作为参数。)
3、通过Construct类实例的方法生成一个Object对象,并且将其转型为被反射的类的类型更便捷的方法:Class对象自带的newInstance()方法对应于用默认构造方法创建被反射类的一个对象。
注意:为生成对象所提供的参数必须与Construct类对象所接受的类型参数一致。
三、反射类的字段
1、类的字段对应的类为Field。
2、Class对象通过类字段的字符串名称识别和取得关于字段的Filed对象。
3、Field对象是对类级别元素的抽象。
4、Field对象需要通过具体对象作为参数才能获得某个对象身上某个字段的值。
说明:
(1)Class可以获得声明过的字段或方法对象。Field对象的任何属性都基于此。因为在获得字段的属性前,必须获得相应的字段对象。
(2)Field可以设置是否压制字段的Java修饰符访问权限。
(3)对于静态字段,是属于类级别的,其也可以通过Class对象作为参数对其进行反射。
四、反射类的方法
1、获得方法类的对象:依据方法名称字符串和方法参数类型从被反射类身上获得。
2、访问方法:依据方法参数值和定义方法的对象或类调用方法。
五、其他与反射相关问题
1、为什么要使用反射:在不能获得类或对象的抽象名称,只能获得关于其的字符串描述的情况下,可以根据字符串描述利用反射机制使用类或对象。
2、反射中的参数个数不匹配的问题:数组类型参数会被编译器自动拆包成多个参数,而不会将其当着一个参数。因此要解决此问题可以将数组类型的参数再次包装一次或者将其进行强制类型转换为其父类型。
3、数组与Object的关系:数组属于Object类型,具体相同元素类型和相同维数的数组属于同一类型。简单数据类型不属于Object类型。
4、数组操作工具:Arrays,可以打印对象类型(非简单类型)数组中的元素列表以及其他操作数组的便捷方法。
5、数组的反射:Array类专门用于对数组的反射进行操作。Class类对象有方法可以判断一个对象是否是数组类型。
6、哈希码的作用:哈希码值是哈希集合存储和访问对象的唯一标识。虽然每一个对象都有自己的哈希码值,但只有将其与哈希集合联系起来才有作用。哈希集合通过哈希码值实现对对象的分级存储和访问,极大的提高了存储速度。哈希集合的缺点是容易引起内存泄露。当对已存于哈希集合中的对象进行修改后,将很难再将其从集合中提取出来。
7、框架的核心机制:调用用户提供的类。
8、配置文件:可以是任意文件名称和格式的文本文件,每一条目占用一行,结尾不加分号。
9、配置文件的加载:输入输出流的加载以工程作为根目录去查找,而类加载器则以当前包名为默认目录进行查找。
六、JavaBean的反射
1、JavaBean:一个特殊的类,具有约定规则的方法名。通常用于传递信息,称为值对象。
2、JavaBean的内省操作与重构方法:
(1)内省操作步骤:根据属性的字符串名称和所属类名称构建属性类对象-》从属性类对象身上获得关于属性的读写方法类对象-》调用读写方法类对象。
与反射的比较:反射需要根据完整的方法字符串名称和参数名称方能从类对象身上获得方法对象,而属性类则仅需要属性的字符串名称和所在的类名就可以获得操作属性方法的方法对象。
这一点是JavaBean所特有的和便利的地方。
(2)重构方法:块代码中所使用的块外变量名和其类型作为方法参数。
3、Introspector复杂内省操作:将类的所有属性和方法反射到BeanInfo对象中,通过BeanInfo对象提供的方法获得属性或者方法的对象集合,最后用遍历的方法对类的各属性或方法进行访问操作。
4、BeanUtils工具:支持对属性的级联操作,支持map和Beans之间的转换。