黑馬程序員——反射深入理解

------- android培訓java培訓、期待與您交流! ----------


仔細重新研究了一遍反射,發現有好多小細節自己理解的並不是很好,現在重新整理筆記。

 

package cn.heima;

import java.lang.reflect.Constructor;

public class ReflectDemo {
	public static void main(String[] args)throws Exception {
		//得到帶有一個參數的構造方法,類型是Constructor,參數類型是StringBuffer.class
		Constructor con1 =String.class.getConstructor(StringBuffer.class);
		//創建一個實例對象,注意兩點,(1)傳遞的參數(2)強制類型裝換
		//使用此 Constructor 對象表示的構造方法來創建該構造方法的聲明類的新實例,
		//並用指定的初始化參數初始化該實例。
		//public T newInstance(Object... initargs) 注意返回類型
		String str =(String) con1.newInstance(new StringBuffer("abc"));
		// 返回 Class 對象,該對象表示聲明由此 Constructor 對象表示的構造方法的類
		System.out.println(con1.getDeclaringClass());
		System.out.println(str);
		//現在是用一個String的字節碼得到構造函數,然後在得到一個實例對象
		//Class-->Constructor-->String
		
		//Class--->String
		//創建str2此處並沒有強轉,爲什麼,個人理解,因爲我用的就是String.class已經確定了字節碼,
		//編譯器已經知道了
		String str2 = String.class.newInstance();
		String str3 = (String)Class.forName("java.lang.String").newInstance();
		System.out.println(str2.length());
		System.out.println(str3.length());
	}

}


 

祥叔經典例子:

		ReflectPoint rp = new ReflectPoint(3,5);
		//fieldY是字節碼對應的變量
		Field fieldY = rp.getClass().getField("y");
		//get()用於獲取某個對象對應的該變量的值
		System.out.println(fieldY.get(rp));
		//私有的需要採用另外的函數getDeclaredField()
		Field fieldX = rp.getClass().getDeclaredField("x");
		//傳說中的暴力反射
		fieldX.setAccessible(true);
		System.out.println(fieldX.get(rp));
		ChangStringValue(rp);
	}

	private static void ChangStringValue(Object obj) throws Exception {
		Field[] fields = obj.getClass().getFields();
		for(Field field:fields){
			if(field.getType()==String.class){
				//得到變量的值
				String oldValue =(String) field.get(obj);
				//字符串的替換方法
				String newValue = oldValue.replace('a', 'b');
				//set()給對象設置新的value
				field.set(obj, newValue);
				System.out.println(field.get(obj));
			}
		}
	}

 

 

	//Method. name表示方法的名稱。例如String類中包含charAt方法,所以才能在此處使用
		//必須是類中確定存在的方法纔可以
		//String.class.getMethod(name, parameterTypes);
		Method charAt = String.class.getMethod("charAt", int.class);
		//charAt.invoke(obj, args)這裏需要加強理解。
		System.out.println(charAt.invoke(str, 1));
		//JDK1.4格式
		System.out.println(charAt.invoke(str, new Object[]{2}));


 

 

	//傳遞一個字符串作爲類名
		String StartingClassName = args[0];
		//得到main()的Method對象
		Method mainMethod =
				Class.forName(StartingClassName).getMethod("main", String[].class);
		//調用方法invokke(),因爲是main,是靜態的,所以第一個參數爲null
		//第二個參數要求必須是Object數組,用兩種方式來表示。
		mainMethod.invoke(null,(Object) new String[]{"dandan","jiaji","qiqi"});
		mainMethod.invoke(null,new Object[]{ new String[]{"dandan","jiaji","qiqi"}});
	}

class Test{
	public static void main(String[] args){
		for(String arg:args){
			System.out.println(arg);
		}
	}
}


 

 

int[] a1 = new int[3];
		int[] a2 = new int[4];
		int[][] a3 = new int[2][3];
		String[] a4 = new String[]{"d","c","b","a"};
		//具有相同維數和元素類型的數組屬於同一個類型,即具有相同的class實例對象。
		System.out.println(a1.getClass()==a2.getClass());
		//System.out.println(a1.getClass()== a3.getClass());
		//System.out.println(a1.getClass()==a4.getClass());
		//數組的父類都是Object
		System.out.println(a1.getClass().getSuperclass().getName());
		System.out.println(a3.getClass().getSuperclass().getName());
		System.out.println(a4.getClass().getSuperclass().getName());
		//異常java.lang.NullPointerException
		//System.out.println(int.class.getSuperclass().getName());
		
		//基本類型的一維數組可以被當做Object類型使用,不能當做Object[]使用
		//Object[] obj1= a1;
		Object[] obj2 = a3;
		Object[] obj3 = a4;
		//Arrays的使用
		System.out.println(Arrays.asList(obj3));



 

		printObject(a4);
	}
	private static void printObject(Object obj) {
		if(obj.getClass().isArray()){
			//得到長度
			int len = Array.getLength(obj);
			for(int i=0;i<len;i++){
				//打印每個元素
				System.out.println(Array.get(obj, i));
				//得到每個元素對應的類型 a[i].getClass().getName()
				System.out.println(Array.get(obj,i).getClass().getName());
				
			}
		}else{
			System.out.println(obj);
		}
	}

 

 


 

		//迷你小框架
		//一定記住用完整的路徑,但是完成的路徑不是硬編碼,而是計算出來的。
//		InputStream in =
//				new FileInputStream("D:\\Workspaces\\MyEclipse10\\javaenhance2\\src\\cn\\heima\\config.properties");
//		InputStream in = 
//				ReflectTest2.class.getClassLoader().getResourceAsStream("\\cn\\heima\\config.properties");
		InputStream in = ReflectTest2.class.getResourceAsStream("config.properties");
		Properties props = new Properties();
		props.load(in);
		String className = props.getProperty("className");
		Collection con1 = (Collection)Class.forName(className).newInstance();

------- android培訓java培訓、期待與您交流! ----------  詳細請查看:http://edu.csdn.net/heima/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章