仔細重新研究了一遍反射,發現有好多小細節自己理解的並不是很好,現在重新整理筆記。
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/