1、反射:java
一、反射指能夠在運行時加載、探知、使用編譯期間徹底未知的類。安全
二、程序在運行狀態中,能夠動態加載一個只有名稱的類,對於任意一個已加載的類,都可以知道這個類的全部屬性和方法;對象
對於任意一個對象,都能調用它的任意一個方法和屬性。blog
三、加載完類後,在堆內存中產生一個Class類型的對象(一個類只有一個Class對象),這個對象包含完整的類的結構信息。內存
經過這個對象看到類的結構。這個對象就像一面鏡子,透過鏡子看到類的結構,稱之爲:反射。get
2、做用io
一、動態加載類、動態獲取類信息(屬性、方法、構造器)編譯
二、動態構造對象class
三、動態調用類和對象的任意方法、構造器效率
四、動態調用和處理屬性
五、獲取泛型信息
六、處理註解
3、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(); } } }
3、操做,獲取類信息
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(); } } }