標籤:
反射就是把Java類中的各種成分映射成相應的java類。
Class類-->java程式中的各個java類屬於同一事物,描述這類事物的Java類名就是Class。
Class.forName的作用:返回類的位元組碼,返回的方式有兩種,一種是這個類曾被載入過,則直接從JVM中返回位元組碼,另一種是JVM中沒用這個類的位元組碼,得用類載入器先將位元組碼載入到JVM中,然後返回位元組碼。
得到類的位元組碼的三種方式
1.類名.class
2.對象.getClass();
3.Class.forName("完整類名");例如: Class.forName("java.lang.String");(多用於反射)
public class ReflectTest { public static void main(String[] args) throws Exception{ String str = "abc"; Class cls1 = str.getClass(); Class cls2 = String.class; Class cls3 = Class.forName("java.lang.String"); System.out.println(cls1==cls2);//true System.out.println(cls1==cls3);//true //判斷是否是基本類型 System.out.println(cls1.isPrimitive());//false System.out.println(int.class.isPrimitive());//true System.out.println(int[].class.isPrimitive());//false System.out.println(int.class==Integer.class);//false System.out.println(int.class==Integer.TYPE);//true }}
View Code
//用反射實現 new String(new StringBuffer("abc") Constructor constructor = String.class.getConstructor(StringBuffer.class); String str1 = (String) constructor.newInstance(new StringBuffer("abc")); System.out.println(str1);//abc
View Code
成員變數的反射(Field類)
//定義一個Point類public class Point { private int x; public int y; public Point(int x, int y) { super(); this.x = x; this.y = y; }}用反射映射Point類Point p = new Point(3,4);Field filedY = p.getClass().getField("y");//getField只能得到可見的屬性System.out.println(filedY.get(p));//得到對象p在屬性y上的具體值 Field filedX = p.getClass().getDeclaredField("x");//getDeclaredField可以得到私人屬性filedX.setAccessible(true);//暴力反射,將私人的設定為可訪問的System.out.println(filedX.get(p));成員變數反射練習public class Cat { String name = "Happy"; String eyes = "Black"; String eat = "beef"; @Override public String toString() { return "Cat [name=" + name + ", eyes=" + eyes + ", eat=" + eat + "]"; } }public class ReflectTest2 { public static void main(String[] args) throws Exception { Cat cat = new Cat(); System.out.println(cat);//Cat [name=Happy, eyes=Black, eat=beef] ChangeCat(cat); System.out.println(cat);//Cat [name=Hbppy, eyes=Blbck, eat=beef] } private static void ChangeCat(Cat obj) throws Exception { Field[] fields = obj.getClass().getDeclaredFields(); for(Field field:fields){ field.setAccessible(true); if(field.getType()==String.class){ String oldStr = (String) field.get(obj); String newStr = oldStr.replace(‘a‘, ‘b‘); field.set(obj, newStr); } } }}
View Code
成員方法反射(Method類)
public class ReflectTest2 { public static void main(String[] args) throws Exception { String str1 = "abc"; Method method = Class.forName("java.lang.String"). getMethod("charAt", int.class); char ch = (char) method.invoke(str1, 1); System.out.println(method.invoke(str1, 1));//b System.out.println(method.invoke(str1, new Object[]{2}));//c }}
View Code
對含有數組參數的成員方法進行反射
//定義一個含有main方法的類class TestArguments{ public static void main(String[] args){ for(String arg : args){ System.out.println(arg); } }}public class ReflectTest { public static void main(String[] args) throws Exception { /*用反射來實現調用main方法*/ String className = args[0]; Method mainMethod = Class.forName(className).getMethod("main", String[].class); mainMethod.invoke(null, (Object)new String[]{"111","222","333"}); mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}}); //以上兩種調用等價,jdk1.5後,會將數組參數進行拆解,這樣上述的一個數組參數就變成了3個參數,則會出現數組個數不匹配, //故應將數組強制轉換成Object或將數組作為一個對象用Object數組進行封裝 }}
View Code
Java學習筆記——反射