黑马程序员---反射

---------------------- 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值