一、反射: 1、反射指可以在運行時載入、探知、使用編譯期間完全未知的類。 2、程式在運行狀態中,可以動態載入一個只有名稱的類,對於任意一個已載入的類,都能夠知道這個類的所有屬性和方法; 對於任意一個對象,都能調用它的任意一個方法和屬性。 3、載入完類後,在堆記憶體中產生一個Class類型的對象(一個類 ...
一、反射:
1、反射指可以在運行時載入、探知、使用編譯期間完全未知的類。
2、程式在運行狀態中,可以動態載入一個只有名稱的類,對於任意一個已載入的類,都能夠知道這個類的所有屬性和方法;
對於任意一個對象,都能調用它的任意一個方法和屬性。
3、載入完類後,在堆記憶體中產生一個Class類型的對象(一個類只有一個Class對象),這個對象包含完整的類的結構信息。
通過這個對象看到類的結構。這個對象就像一面鏡子,透過鏡子看到類的結構,稱之為:反射。
二、作用
1、動態載入類、動態獲取類信息(屬性、方法、構造器)
2、動態構造對象
3、動態調用類和對象的任意方法、構造器
4、動態調用和處理屬性
5、獲取泛型信息
6、處理註解
三、Class類對象
getClass() 、 Class.forName() 、 .class 語法
public class Demo01 { public static void main(String[] args) { String path = "cn.lhl.Test.bean.User"; try { Class clazz = Class.forName(path); //對象是表示和封裝一些數據。 //一個類被載入後,JVM會創建一個對應的Class對象,類的全部結構會放到對應的Class對象中。 //通過Class看到對應類的信息 System.out.println(clazz); Class clazz1 = String.class; Class clazz2 = int.class; Class clazz3 = path.getClass(); } catch (Exception e) { e.printStackTrace(); } } }
三、操作,獲取類信息
package cn.lhl.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** *通過反射的API ,獲取類的信息 * * @author Administrator * */ public class Demo02 { public static void main(String[] args) { String path = "cn.lhl.Test.bean.User"; try { Class clazz = Class.forName(path); //獲取類的名字 System.out.println(clazz.getName());//包名和類名 System.out.println(clazz.getSimpleName());//類名 //獲取屬性信息 // Field[] fields = clazz.getFields();//只能獲得public的field Field[] fields = clazz.getDeclaredFields();//獲得所有的field Field f = clazz.getDeclaredField("uname"); System.out.println(fields.length); for(Field temp:fields) { System.out.println(temp); } //獲取方法信息 Method[] methods = clazz.getDeclaredMethods(); Method m01 = clazz.getDeclaredMethod("getUname", null); Method m02 = clazz.getDeclaredMethod("setUname", String.class);//如果有參,必須傳遞參試類型對應的class對象 for(Method m:methods) { System.out.println(m); } //獲取構造器信息 Constructor[] constructors = clazz.getDeclaredConstructors();//所有構造 Constructor c = clazz.getDeclaredConstructor(null);//空構造 Constructor c1 = clazz.getDeclaredConstructor(int.class,int.class,String.class);//有參構造 for(Constructor temp:constructors) { System.out.println(temp); } } catch (Exception e) { e.printStackTrace(); } } }
package cn.lhl.Test; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import cn.lhl.Test.bean.User; /** *通過反射API動態操作:構造器、方法、屬性 * @author Administrator * */ public class Demo03 { public static void main(String[] args) { String path = "cn.lhl.Test.bean.User"; try { Class<User> clazz = (Class<User>) Class.forName(path); //通過反射API調用構造方法,構造對象 User u = clazz.newInstance(); //調用了User無參構造方法 System.out.println(u); Constructor<User> c = clazz.getDeclaredConstructor(int.class,int.class,String.class); User u1 = c.newInstance(100,18,"華哥"); System.out.println(u1.getUname()); //通過反射API調用普通方法 User u2 = clazz.newInstance(); Method method = clazz.getDeclaredMethod("setUname",String.class); method.invoke(u2, "華哥二"); System.out.println(u2.getUname()); //通過反射API操作屬性 User u3 = clazz.newInstance(); Field f = clazz.getDeclaredField("uname"); f.setAccessible(true); //這個屬性不需要安全檢查,可以直接訪問,可以提高效率(大概為4倍) f.set(u3, "華哥三"); //通過反射直接寫屬性 System.out.println(u3.getUname());//通過反射直接讀取屬性的值 System.out.println(f.get(u3)); } catch (Exception e) { e.printStackTrace(); } } }