黑马程序员_反射知识总结

------------------------------------------------android培训java培训期待与您交流!-----------------------------------------------

一般的类和Class类的区别

一般的类对象包含常见事物的属性信息,可以认为Class是一般类对象更深一层的抽象,Class对象里面包含类的方法,有字段,有父类,有包等等信息

Class.fromName()的作用:返回字节码
 返回字节码有两种方式:当JVM中有的该字节码时候就直接返回该字节码, 如果JVM没有该字节码的时候就让类加载器去加载该字节码并缓存在JVM中以后好使用

得到字节码的方式有三种:只有一份字节码
通过类名例如,System.class
通过对象例如,new Date().getClass()
通过Class.forName("类名")例如,Class.forName("java.util.Date");

反射就是把Java类中的各种成分映射成相应的java类

①构造方法:
例子:Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
编译时不知道是谁的构造方法因为好多个类都有构造方法所以需要强制类型转换
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象
Class.newInstance()方法:该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

②反射字段:

ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");//getField可以得到public的那个属性对象
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");//可以得到protected和private的那个属性对象
fieldX.setAccessible(true);//但是要访问private对象的值还需要对其访问设置为true
System.out.println(fieldX.get(pt1));

反射字段的运用场景:可以把框架配置文件里面的某些内容换掉

private static void changeStringValue(Object obj) throws Exception
	{
		Field[] fields = obj.getClass().getFields();
		for (Field field : fields)
		{// 获取属性的类型用getType()方法,因为字节码只有一份所以用==比equals更专业
			if (field.getType() == String.class)
			{
				String oldValue = (String) field.get(obj);
				String newValue = oldValue.replace('b', 'a');
				field.set(obj, newValue);
			}
		}
	}

③反射方法
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
new String[]{"111","222","333"}是一个object数组java会把包里面的内容打开
解决方案有两个一是把数组告诉编译器不要拆包(Object)new String[]{"111","222","333"}
编译器会作特殊处理,编译时不把参数当作数组看待,也就不会把数组拆包了
还有一个方案是把数组再进行一次打包new Object[]{new String[]{"111","222","333"}}
null说明是静态方法
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});

④数组与Object的关系及其反射类型  
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
字节码相同的前提是

1要数组类型相同,2要维数相同
System.out.println(a1.getClass() == a2.getClass());//相同
System.out.println(a1.getClass() == a4.getClass());//不相同,类型不同
System.out.println(a1.getClass() == a3.getClass());//不相同,维数不相同
Object aObj1 = a1;//数组是对象
Object aObj2 = a4;//数组是对象
Object[] aObj3 = a1;//错误
Object[] aObj4 = a3;//对象数组,里面的元素是int数组
Object[] aObj5 = a4;//对象数组,里面的元素是String
由于a1对应不上JDK1.4里面的数组asList(Object[] a),
那么就交给JDK1.5里面的 asList(T... a)然后就把它当作一个对象
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4)); 

⑤数组反射的运用

传递一个对象如果是数组就依次打印出数组里面的内容,如果是单个对象就打印出这个对象

private static void printObject(Object obj)
	{
		Class clazz = obj.getClass();
		if (clazz.isArray())
		{
			int len = Array.getLength(obj);
			for (int i = 0; i < len; i++)
			{
				System.out.println(Array.get(obj, i));
			}
		} else
		{
			System.out.println(obj);
		}

	}

ArrayList_HashSet的比较及Hashcode分析
ArrayList里面可以放相同的对象引用,HashSet里面不可放相同的对象引用 

hashCode的作用

根据对象提供的hashCode值把对象放到不同的区域里边,只有那个集合实现了hash算法那么hashCode才有价值

Java中的内存泄漏

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(pt1); 
当一个对象被存储进HashSet集合之后,就不要修改这个对象中那些参与计算哈希值的字段了,如果修改了对象的哈希值那么与最初存进HashSet集合中的哈希值就不同了,再去删除该对象的时候在那个区域就找不到该对象,就删除不了,长久下去就会导致内存泄漏

(java中的内存泄漏:数据库没有关闭,java垃圾回收会把对象干掉但是数据库那边的资源却没有被关闭)
pt1.y = 7;  
collections.remove(pt1);
System.out.println(collections.size());

反射的目的在于调用还没有写出来的类

getResourceAsStream()方法从根目录下找文件也就是那个classPath目录下
InputStream ips = ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
相对于ReflectTest2类所在路径下的资源(config.properties在这个cn.itcast.day1包里面)
InputStream ips = ReflectTest2.class.getResourceAsStream("config.properties");
相对于ReflectTest2类所在路径下子包的资源(config.properties在这个cn.itcast.day1.resources包里面)
InputStream ips = ReflectTest2.class.getResourceAsStream("resources/config.properties");
config.properties同ReflectTest2所在的包没有关系那么就用绝对路径
InputStream ips = ReflectTest2.class.getResourceAsStream("/cn/itcast/day1/resources/config.properties");

----------------------------------------- android培训java培训、java学习型技术博客、期待与您交流! --------------------------


详情请查看:http://edu.youkuaiyun.com/heima




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值