java構造方法、成員變數、方法所對應的反射例項
最原始的class類中包含著一些構造器,包,方法,屬性等等內容,我們可以通過位元組碼檔案得到對應的一個構造器
,並指明是那種構造器通過引數進行設定,然後通過Constructior類進行例項物件
package test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; /** * @author Dqd * 構造方法的反射 Constructor類 * 成員變數的反射 Field類 * 方法的反射 Method類 * 通過反射的方式呼叫main方法 * */ public class test { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { //構造方法的反射,通常通過類得到構造器然後通過newInstance()來建立例項 Constructor<?>[] con = stu.class.getConstructors(); stu st1 = (stu)con[0].newInstance(3,4); //通過getField來得到可以訪問的變數,然後Field變數對應到相應的實力上取出對應值 //如果我們通過st1.getClass().getField("x"),因為X為私有所以不能訪問但是可以通過DeclaredField訪問 //尚若檢視需要用到包級反射,修改許可權,最後才能列印 Field f = st1.getClass().getDeclaredField("x"); f.setAccessible(true); System.out.println(f.get(st1)); //通過修改位元組碼檔案來對String型別中的'a'改變成為'b' changeCharAtoB(st1); System.out.println(st1); //方法的反射 String str="abc"; Method methodCharAt = String.class.getMethod("charAt", int.class); //invoke作用於那個物件的身上(物件和方法沒有什麼關係) System.out.println(methodCharAt.invoke(str, 1)); //如果invoke()的第一個引數為null,那麼意味是靜態的方法 //正常的情況下我們呼叫main方法 /*TestArguements.main(new String[]{"123","456"});*/ //通過反射來呼叫,為什麼要通過反射去掉用呢?我們可能會遇到給main方法傳一些引數但是不知道去執行哪個類 String starClassName = args[0]; Method mainMethod = Class.forName(starClassName).getMethod("main", String[].class); //這裡使用一個object[]的原因是java傳進去陣列,會自動的拆開String相當於傳了兩個引數而實際上只需要一個 mainMethod.invoke(null,new Object[]{ new String[]{"123","456"}}); //或者使用下面的 //mainMethod.invoke(null,( Object)new String[]{"123","456"}); int [] a1 = {1,2,3}; int[][] a2 = new int[2][3]; String[] a3 = {"123","456"}; //輸出的結果分別是[[
[email protected]],[123, 456]後者屬於Object[](因為接收時分為Object[]和<T>型別),而String[]符合 //但是int[]不符合只能按照jdk1.4的以物件形式輸出 System.out.println(Arrays.asList(a1)); System.out.println(Arrays.asList(a3)); } public static void changeCharAtoB(Object obj) throws IllegalArgumentException, IllegalAccessException{ Field[] fields = obj.getClass().getFields(); for(Field f:fields){ //if(f.getType().equals(String.class){ //位元組碼的比較使用等號因為實用的位元組碼 if(f.getType()==String.class){ String oldVal = (String) f.get(obj); String newVal = oldVal.replace('a', 'b'); f.set(obj, newVal); //System.out.println(newVal); } } } } class TestArguements{ public static void main(String[] args){ for(String s:args){ System.out.println(s); } } }
stu:
package test;
public class stu {
private int x;
public int y;
public String str1="ball";
public String str2 = "basket";
public stu(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return str1 +'\n'+" "+str2;
}
}