黑马程序员---反射

来源:互联网 发布:js获取frame中的元素 编辑:程序博客网 时间:2024/05/16 19:05
---------------------- android培训、java培训、期待与您交流! ----------------------
Java的反射并不是什么新特性早在jdk1.2中就有了。

反射就是把Java类中的各种成分映射成相应的Java类。
我们在学习反射中一个一定要接触到的 类就是Class,Class是反射的基石,没有Class这个类我们便没有办法进行反射。
Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则由这个类的实例对象来确定,不同的实例对象有不同的属性值。Java程序中各个Java类,它们是否属于同一类事物,是不是可以用一个类来描述这类事物呢?这个类的名字就是Class。Class描述了有关于类的名字,类的访问属性,类所属的包的名字,字段名称列表,方法的列表。获取类中的字节码并不能直接通过new Class()这种方式来进行获取的,每一个类型的字节码在内存中只有一份。
得到字节码的方式有三种
1.直接通过类名.class
2.对象.getClass();
3.Class.forName():这种方法的加载机制是,若是Java虚拟机又要加载的字节码的话就直接返回,若是没有的话就将要加载的字节码加载到Java虚拟机中并缓存起来,以便以后的加载。
总之,只要在源程序中出现的类型,都有各自的Class实例对象。
除了以上的Class类之外还有Field、Method、Contructor、Package等。
Contructor对象代表一个构造方法,它可以得到类中构造方法的名字,所属的类,产生的实例对象。
Field代表某个类中的成员变量
ReflectPoint rp = new ReflectPoint(3,5);Class clazz = rp.getClass();Field fieldX = clazz.getField("x");System.out.println(fieldX.get(rp));Field fieldY = clazz.getDeclaredField("y");fieldY.setAccessible(true);System.out.println(fieldY.get(rp));
上面的代码getDeclaredField("y")和fieldY.setAccessible(true);叫做暴力反射。我们来个实例的应用
/对某个字符串内容改变private static void changeStringValue(Object obj)throws Exception{//将传进来的类的成员全部获取出来Field[] fields = obj.getClass().getFields();//判断要获取的类的成员的类型有没有String类型的for (Field field : fields){//这里我们用==这个符号合适,//用equals方法比较不合适,如是大家都是string类型的话那比起来就没有意义if(field.getType()==String.class){//若是有的话就将字段获取出来String oldValue = (String)field.get(obj);//通过String类中的replace方法将我们要替换的值替换掉。String newValue = oldValue.replace('a','b');//修改好之后便将新的值写会到对象中field.set(obj,newValue);}}}
下面是对面方法和内存泄漏的一个小例子
import java.util.*;import java.io.*;class ReflectTest2 {public static void main(String[] args)throws Exception {//InputStream ips = new FileInputStream("configuration.properties");//有关于配置文件存放的问题这个是值得我们考虑的,//我们到底要把配置文件那在哪里呢???我们可以在参数中写一个绝对路径,//但是考虑到我们的程序给用户之后,用户没有这个路径那就挂//我们有更好的方法就是通过类加载器来加载我们的配置文件,//那就是将我们的配置文件放在我们的classpath路径想,由类加载器帮我们加载//实现的代码:InputStream ips = ReflectTest2.class.getClassLoder.getResourceAsStream("我们项目所在的路径");//但是这种方法有缺陷就是只能读取,不能写入InputStream ips = ReflectTest.class.getResourceAsStream("configuration.properties");Properties props = new Properties();props.load(ips);ips.close();String className = props.getProperty("className");Collection collections = (Collection)Class.forName(className).newInstance();//Collection collections = new ArrayList();//Collection collections = new HashSet();ReflectPoint pt1 = new ReflectPoint(3,3);ReflectPoint pt2 = new ReflectPoint(5,5);ReflectPoint pt3 = new ReflectPoint(3,3);collections.add(pt1);collections.add(pt2);collections.add(pt3);collections.add(pt3);//pt.x=7;//当这里改掉之后原来的那个对象的hash值就被改变了所以就删不了原来的那个对象,//就会造成内存溢出//内存泄漏就是当对象没有用时,有没有被虚拟机给回收掉一直在占用内存空间,就是内存泄漏//collections.remove(pt1);System.out.println(collections.size());}}
通过了这个反射的学习,让我知道了什么是反射,怎用反射,用在哪里。


---------------------- android培训、java培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net/heima
原创粉丝点击