---------------------- android培训、java培训、期待与您交流! ----------------------
反射(2):
1:Method类
代表某个类中的成员方法
用一个对象的getMethod()方法获得对应方法对象,getMethod()方法中需要传入对应方法名<与方法中的参数的字节码类型
一个方法对象的invoke方法可以传入一个对象,和参数 来实现方法功能 如果这个方法是静态的 那么传入的对象可以为null
当我们调用一个类的main方法时,invoke方法传入的对象可以为null,因为main方法是静态的,第二个参数传入一个String数组,但是因为jdk1.5兼容1.4,在方法运行时它会将数组拆开,变成多个参数,所以我们需要将String数组用一个Objrct数组包装,避免这种情况发生,因为String数组就是一个Object,我们也可以在数组前面用Object转换类型
当我们需要向想要运行的类中传递参数时,可以
鼠标右键-->Run As-->Run Configurations-->Arguments-->Program arguments 传入参数
2:数组与Object的关系及其反射类型
拥有相同元素类型和相同维度的数组属于同一种类型,有相同的class
数组进行转换时,基本数据类型一维数组无法转换成Object,因为基本数据类型的对象不是Object的子类,但是基本数据类型多维数组可以,因为基本数据类型数组的对象是Object的子类
注意:
我们无法直接打印出数组中的元素出来,如果想打印出来,就需要用到Arrays类中的asList()方法传入数组才能打印出数组中的元素,这是我们用到的jdk1.4中asList()传入数组将数组转换成list的结果(list可以直接打印出值),但是一个基本数据类型的数组却无法打印出元素,只会打印出地址,因为在jdk1.4中asList()中传入的是一个Object类型的数组,int型并非他的子类,所以无法使用而会转到1.5的方法中,而1.5的方法中是将传入的参数当做一个数组中的Object元素传入传入,所以打印地址
我们可以得到数组中每个元素的类型,但是无法得到数组的类型,因为数组可以是0bject类型,其中可以存放多种类型
java.lang.reflect.Array类是对数组反射相关的一些类
3:HashCode与HashSet类
关于HashCode,使用到哈希值的大多数都是Hash集合,而哈希值大多数值的是对象地址值,在HashSet中会首先比较HashCode,将内存地址值相等的元素规定为同一区域,然后再以equals()比较内容同一区域的内容是否相等来确定是否存入元素,可以提高性能
所以在同时会运用到HashCode和equals()时,equals()相等最好将HashCode也设置相等
4:HashCode有关内存泄漏问题
当一个对象已经存储进HashSet中后,就不要修改这个对象中那些参与计算哈希值的字段了,否则会导致这个对象的哈希值与存入哈希值不同,而规划到别的哈希值区域,而删除动作会寻找初始哈希值删除,所以无法删除集合中的该对象,会导致内存泄露
其实这个对象也是卡可以删除的,只是较为麻烦,我们可以把HashSet中的元素存入ArrayList中,然后将HashSet清空,然后查找ArrayList中该对象的位置,然后删除,再将ArrayList中的元素重新导入HashSet就可以了
5:反射的作用
框架与工具类的区别:
工具类被用户的类调用,而框架式调用用户提供的类
因为写程序是无法知道某个要调用的类(可能还没有这个类),所以,在程序中无法直接new某个类的实例对象,这时候就需要用到反射
我们可以在一个类中传入配置文件,以后如果那个实例将要被调用时可以更改配置文件,配置文件properties类型
6:配置文件与类加载器
在一个文件中使用输入流获取这个配置文件文件,然后建立一个properties,用properties的load方法获取配置文件中的键值对(properties与Hash的区别就是properties可以直接获取文件上的键值对) 然后可以用properties对象的getProperty()方法输入键获取对应的值,然后用反射获取对应对象使用
在我们用输入流获取配件文件时 最好输入绝对路径,但是因为我们不知道用户所安装盘符,所以可以用getRealPath()获取工程所在盘符,然后加上配置文件目录组成绝对路径
也可以用类加载器(当前类的字节码的getClassLoader())的getResourceAsStream()方法传入要查找的配置文件名,类加载器会直接在class文件工程目录下查找(所以我们输入配置文件名时,需要将包名放在前面),但是在我们使用eclipse是可以直接将配置文件放入源文件包中,因为eclipse编译文件时会将所有源文件编译成class文件,非java文件直接复制一份到class文件目录
这种方法只能获得一个输入流,却无法获得输出流,它是只读的
框架的配置文件都是以这种方式获得的
也可以直接使用类的对象所携带的getResourceAsStream()方法,这个方法直接查找类对象所在的包,也可以设置为绝对路径查找(内部也是调用的getClassLoader())
JavaBean与内省机制的初级概念:
1:JavaBean细解
IntroSpector(内省) --> JavaBean --> 特殊的Java类(类中有方法以特定规则命名的:set,get打头)
把一个类当作一个JavaBean用,属性根据get,set方法来确定,而不是根据类的属性名
javaBean的属性名是把get,set方法中的get,set去掉,然后看第二个字母是大写还是小写的,如过是大写,则把第一个字母写成大写,是小写,就将第一个字母写成小写
2:对JavaBean的简单内省操作
如果在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中(这些信息是私有的,可以用公用方法访问),这种JavaBean的实例对象通常称为值对象(Value Object 简称VQ)
如果想要获得一个JavaBean中的set或者get方法的话,可以建立一个
PropertyDescriptor(属性操作符)对象,里面传入要获取的set或者get方法操作的属性名名和方法所在类名,来获取类的属性
然后用PropertyDescriptor的getReadMethod()和getWriteMethod()方法就可以获得set或者get方法的字节码,然后就可以用方法字节码的invoke()方法操作对象了
get方法有返回值,所以需要用一个值接收,但是不需要传入参数
set方法没有返回值,不需要接收,但是需要传入参数
---------------------- android培训、java培训、期待与您交流! ----------------------