用反射機制簡單應用配置文件

  首先在建立一個配置文件config.properties

package javatribe.fts.reflect;

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

public class ReflectTest3 {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		//InputStream ips=new FileInputStream("config.properties");
       
		//InputStream ips=ReflectTest3.class.getClassLoader().getResourceAsStream("javatribe/fts/reflect/config.properties");
		InputStream ips=ReflectTest3.class.getResourceAsStream("resources/config.properties");
		
		Properties props=new Properties();
        props.load(ips);
        ips.close();
        String className=props.getProperty("className");
        Collection cllections=(Collection) Class.forName(className).newInstance();
		
        ReflectPoint pt1=new ReflectPoint(3,3);
        ReflectPoint pt2=new ReflectPoint(5,5);
        ReflectPoint pt3=new ReflectPoint(3,3);
        cllections.add(pt1);
        cllections.add(pt2);
        cllections.add(pt3);
        cllections.add(pt1);
        
 
        System.out.println(cllections.size());
	}

}

如果配置文件寫:className=java.util.HashSet  則輸出結果是2

如果配置文件寫:className=java.util.ArrayList 則輸出結果是4

這是爲什麼呢?

ArrayList是有序集合,相當於數組。存放的是外面對象的引用。這裏對象可以重複。而HashSet存放的對象不能重複

這個時候得分析一下hashCode的用處了,下面用簡單代碼說明?

package javatribe.fts.reflect;

public class ReflectPoint {
	private int x;
	public int y;
	public String str1="ball";
	public String str2="basketball";
	public String str3="itcast";
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final ReflectPoint other = (ReflectPoint) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}



	@Override
	public String toString(){
		return str1+" : "+str2+" : "+str3;
		
	}
}

package javatribe.fts.reflect;

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

public class ReflectTest2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        //Collection cllections=new ArrayList();
        Collection cllections=new HashSet();
        ReflectPoint pt1=new ReflectPoint(3,3);
        ReflectPoint pt2=new ReflectPoint(5,5);
        ReflectPoint pt3=new ReflectPoint(3,3);
        cllections.add(pt1);
        cllections.add(pt2);
        cllections.add(pt3);
        cllections.add(pt1);
        
        //pt1.y=7;
        //cllections.remove(pt1);
        System.out.println(cllections.size());
        
	}

}

這個時候輸出的結果是2

要是我打開註釋呢?

        //pt1.y=7;
        //cllections.remove(pt1);

輸出結果依舊是2

如果我我打開註釋呢?

//cllections.remove(pt1);
輸出的結果是1

這是爲什麼呢?

        hashcode在存儲值得時候把數值分爲若干值域,把將要存入的數據轉化爲HashCode碼(通過一定的算法得到)後放入不同的區域,當有相同的對象的時候也根據hash算法算出具體的值,根據具體的值在對用的區域去匹配,而不是一個一個從頭開始匹配,這樣提高了存儲效率。
        當對象被存儲進HashCode集合中以後,就不能修改這個對象中的那些參與計算哈希值得字段,否則,對象修改後的哈希值與最近存儲進HashSet集合中時的哈希值就不同了,在這種情況下,即使在contains 方法使用該對象當前的引用作爲參數去HashSet集合檢索對象,也將返回找不到對象的結果,這也會導致無法從HashSet集合中單獨刪除當前對象,從而造成內存泄露
        

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章