黑马程序员--数组的反射,反射的实现框架实例,配置文件加载

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

数组的反射:

l 具有相同元素和维数类型的数组属于同一个类型,就是具有相同的Class实例对象。

l 代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Calss

l 基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用。

l Arrays.asList()方法处理int[]String[]时的差异;

package com.hncu.day2;

import java.util.Arrays;

public class ArrayReflectDemo {

	public static void main(String[] args) {
		int[] a = new int[]{3,5,8};
		String[] s = new String[]{"com","sun","ibm"};
		System.out.println(a.getClass().getSuperclass());
//打印class java.lang.Object
		System.out.println(s.getClass().getSuperclass());
//打印class java.lang.Object
		
		System.out.println(Arrays.asList(a));//[[I@dc8569]
		System.out.println(Arrays.asList(s));//[com, sun, ibm]

		/*asList()接受的参数是Object[]类型的数组,由于String[]属于Object[] 而int[]不属于Object[],
		 int[]会被当作一个对象类型,打印出该对象,而String会被打印出数组中的元素。
		 */
	}
}

打印数组对象以及对象中的内容:

import java.lang.reflect.Array;
import java.util.Arrays;

public class ArrayReflectDemo {

	public static void main(String[] args) {
		int[] a = new int[]{3,5,8};
		String[] s = new String[]{"com","sun","ibm"};
		printObject(a);
		printObject(s);
		printObject("hncu");
	}

	private static void printObject(Object obj) {
		Class cls = obj.getClass();
		if(cls.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);
		}
	}
}
打印结果:
3
5
8
com
sun
ibm
Hncu


 

hashCode方法与HashSet

如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息。如果是一个集合中有很多元素,譬如有一万个元素,并且没有包含要查找的对象时,则意味着你的程序需要从该集合中取出一万个元素进行啄一的比较才能得到结论,有人发明了一种hashCode算法,来提高查找的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域,

hashSet就是采用哈希算法存储对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组的划分对象的存储区域。Object中的hashCode用来返回对就java对象的哈希码,从而提高查找的效率。

为了保证一个类的实例对象能在HashSet正常存储,要求这个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,也就是说,如果obj1.equals(obj2)的结果为true,那么一下表达式的结果页要为true

obj1.hashCode() == obj2.hashCode()

如果一个类的hashCode()方法没有遵循上述要求,那么,当这个的两个实例对象用equals()方法比较的结果相等时,它们本来应该无法同时存储进Set集合中,但是,如果将它们存储进HashSet集合中时,由于它们的hashCode()方法的返回值不同,第二个对象首先按哈希码计算可能会被放进与第一个对象不同的区域中,这样,它就不可能与第一个对象进行equals方法比较了,也就可能被存储进HashSet集合中了。Object类的hashCode()方法不能满足对象被存入到HashSet中的要求,因为它的返回值是通过对象的内存地址推算出来的,同一个对象在程序运行期间的任何时候返回的哈希值都是始终不变的,所以,只要是两个不同的实例对象,即使它们的equals方法比较结果相等,它们默认的hashCode方法的返回值是不同的。

提示:

1)通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即euqlas方法比较结果不相等的对象可以有相同的哈希码,或者说哈希码相同的两个对象的equals方法比较的结果可以不等,例如,字符串“BB”"Aa"euqals方法比较结果肯定不相等,但它们的hashCode方法返回值却相等。

2)当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在cantains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果。这也会导致从HashSet集合中单独删除当前对象,从而造成内存泄露

package com.hncu.day2;

import java.util.Collection;
import java.util.HashSet;

public class ReflectDemo2 {
	
	private int x;
	private int y;
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ReflectDemo2 other = (ReflectDemo2) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}

	public ReflectDemo2(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	
	public static void main(String[] args) {
		Collection<ReflectDemo2> collection = new HashSet<ReflectDemo2>();
		ReflectDemo2 ref1 = new ReflectDemo2(2,4);
		ReflectDemo2 ref2 = new ReflectDemo2(2,4);
		ReflectDemo2 ref3 = new ReflectDemo2(3,4);
		collection.add(ref1);
		collection.add(ref2);
		collection.add(ref3);
		ref3.x=6;
		collection.remove(ref3);//ref3修改了参与计算哈希值的字段X,所以哈希值也改变,该对象存放到别的区域中,打印结果为2。
		System.out.println(collection.size());
		
		//覆盖hashCode和equals后ref1和ref2就被当作同一个对象,无法同时存入集合中。打印结果为2。
		//没有覆盖这两个方法时,ref1和ref2是不同的对象,可以被存入集合中。
		//只覆盖equals方法而不覆盖hashCode方法,ref1和ref2的哈希值不同,会被当作两个对象存入集合中
	}
}


反射的作用:实现框架功能

package com.hncu.day2;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;

public class ReflectDemo2 {

	private int x;
	private int y;

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ReflectDemo2 other = (ReflectDemo2) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}

	public ReflectDemo2(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public static void main(String[] args) throws Exception {
		InputStream ip = new FileInputStream("config.properties");
		Properties props = new Properties();
		props.load(ip);// 加载配置文件
		ip.close();
		String className = props.getProperty("className");
		Collection collection = (Collection) Class.forName(className)
				.newInstance();
		// new的是配置文件的中ArrayList,会被全部加进去

		ReflectDemo2 ref1 = new ReflectDemo2(2, 4);
		ReflectDemo2 ref2 = new ReflectDemo2(2, 4);
		ReflectDemo2 ref3 = new ReflectDemo2(3, 4);
		collection.add(ref1);
		collection.add(ref2);
		collection.add(ref3);

		System.out.println(collection.size());

	}

}


 

配置文件:config.properties(存放在当前项目的路径下)

className=java.util.ArrayList

 

使用类加载器方法管理配置文件和资源。

方法一:

//使用类加载器加载配置文件,配置文件要放在Class文件所在的目录。

InputStream ip=ReflectDemo2.class.getClassLoader().getResourceAsStream("config.properties");

方法二:没有使用类加载器

InputStream ip = ReflectDemo2.class.getResourceAsStream("/config.properties");

//使用的绝对路径

 

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值