程序運行的時,能夠改變程序結構或變量類型。典型的語言: Python,ruby,javascript等 如javascript代碼: function test(){ var s = "var a = 3, var b = 4; alert(a+b)"; eval(s); } C、C++、Java不是動態語言,可是Java有必定的動態性,咱們能夠利用反射機制、字節碼操做得到相似動態語言的特性。 Java的動態性讓編程的時候更加靈活。
指的是能夠運行時加載、探知、使用編譯期間徹底未知的類。javascript
程序在運行狀態中,能夠加載一個只有名稱的類,對於任意一個已加載的類,都可以知道它的方法 和屬性,對於任意一個對象,都能調用它的任意一個方法和屬性。java
加載完類以後,在堆內存(HotSpot虛擬機是在方法區),就會產生一個Class對象(一個類只用一個Class 對象),這個對象包含整個類的結構信息。咱們能夠經過這個對象看到類的結構。這個對象就像一面鏡子,經過這個鏡子能夠個看到 類的結構,因此咱們稱之爲「反射」。編程
jdk對Class的介紹:數組
Class類的實例表示正在運行的Java應用程序中的類和接口。枚舉是一種類,註釋是一種接口。每一個數組屬於被映射爲Class 對象的一個類,全部具備相同元素類型和維數的數組都共享該 Class 對象。基本的Java 類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示爲 Class 對象。 Class沒有公共構造方法。Class對象是在加載類時由Java虛擬機以及經過調用類加載器中的defineClass方法自動構造的。ruby
總結:this
Class類的對象包含了某個被加載類的結構,一個被加載類的對應一個Class對象。spa
當一個類被加載,或當加載器的defineClass()被JVM掉用,JVM便自動產生一個Class對象。.net
Class類是反射的根源。code
public class ClassTest { public static void main(String[] args) throws ClassNotFoundException { // (1)forName()獲取Class對象(最經常使用) Class clazz1 = Class.forName("reflection.Student"); System.out.println(clazz1.hashCode()); // (2).class獲取Class對象 Class clazz2 = String.class; System.out.println(clazz2.hashCode()); // (3)getClass()獲取Class對象 // 一個類只對應一個Class對象 Class clazz3 = "reflection.Student".getClass(); System.out.println(clazz3.hashCode()); //每一個數組屬於被映射爲Class對象的一個類,全部具備相同元素類型和維數的數組都共享該Class對象 int[] arr01 = new int[10]; int[][] arr02 = new int[30][3]; int[] arr03 = new int[30]; double[] arr04 = new double[10]; System.out.println(arr01.getClass().hashCode()); System.out.println(arr02.getClass().hashCode()); System.out.println(arr03.getClass().hashCode()); System.out.println(arr04.getClass().hashCode()); } }
public class Student { public String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } private void myPrivateMethod(){ } public Student(String name, int age) { this.name = name; this.age = age; } //默認構造器反射的時候不要省略 public Student() { } } public class ClassTest { public static void main(String[] args) throws Exception { // 得到類型 Class clazz = Class.forName("reflection.Student"); System.out.println(clazz.getName()); System.out.println(clazz.getSimpleName()); // 得到屬性 // 獲取所有方法 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("所有的屬性:" + field.getName()); } // 獲取public修飾的方法 Field[] fields1 = clazz.getFields(); for (Field field : fields1) { System.out.println("私有的屬性:" + field.getName()); } // 得到方法 // 得到所有方法 Method[] methods = clazz.getDeclaredMethods(); // 方法名字 + 無參數 Method m01 = clazz.getDeclaredMethod("getName", null); // 方法名 + 有參數 Method m02 = clazz.getDeclaredMethod("setName", String.class); for(Method m:methods){ System.out.println("方法:"+m); } // 得到構造器 Constructor[] constructors = clazz.getDeclaredConstructors(); Constructor c = clazz.getDeclaredConstructor(String.class, int.class); System.out.println("得到構造器:"+c); for(Constructor temp:constructors){ System.out.println("構造器:"+temp); } } } //反射生成對象、調用普通方法、修改屬性 public class ClassTest3 { public static void main(String[] args) throws Exception { //默認構造器產生對象 Class<Student> clazz = (Class<Student>) Class.forName("reflection.Student"); System.out.println(clazz.newInstance()); //指定構造器產生對象 Constructor<Student> c = clazz.getDeclaredConstructor(String.class, int.class); Student student = c.newInstance("xiaoming", 12); System.out.println("指定構造器產生對象後獲取姓名: " + student.getName()); //反射調用普通方法 Method m = clazz.getDeclaredMethod("setName", String.class); m.invoke(student, "XIAOHUA "); System.out.println("反射調用普通方法修改姓名後獲取姓名: " + student.getName()); //修改該屬性 Student student1 = clazz.newInstance(); Field field = clazz.getDeclaredField("name"); field.setAccessible(true); field.set(student1, "wjk"); System.out.println(student1.getName()); System.out.println(field.get(student1)); } }
setAccessible(boolean flag)對象
(1) 將此對象的 accessible 標誌設置爲指示的布爾值。值爲 true 則指示反射的對象在使用時應該取消 Java 語言訪問檢查。值爲 false 則指示反射的對象應該實施 Java 語言訪問檢查。
(2) 設置false效率提升。
//驗證 public class ClassTest4 { public static void test1() { Student student = new Student(); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { student.getName(); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void test2() throws Exception { Student student = new Student(); Class clazz = student.getClass(); Method method = clazz.getDeclaredMethod("getName", null); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { method.invoke(student); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void test3() throws Exception { Student student = new Student(); Class clazz = student.getClass(); Method method = clazz.getDeclaredMethod("getName", null); method.setAccessible(true); long start = System.currentTimeMillis(); for (Long i = 1L; i < 1000000L; i++) { method.invoke(student); } long end = System.currentTimeMillis(); System.out.println(end - start); } public static void main(String[] args) throws Exception { test1(); test2(); test3(); } } //結果 37 72 48
public class ClassTest5 { public static void test1(List<String> strings, Map<String, Object> map) { System.out.println("test1"); } public static List<String> test2() { return null; } public static void main(String[] args) throws Exception { Class clazz = ClassTest5.class; Method m = clazz.getMethod("test1", List.class, Map.class); Type[] t = m.getGenericParameterTypes(); for (Type type : t) { System.out.println("#" + type); if (type instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) type).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("泛型類型:" + genericType); } } } Method m2 = ClassTest5.class.getMethod("test2", null); Type returnType = m2.getGenericReturnType(); if (returnType instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("返回值,泛型類型:" + genericType); } } } } //結果 #java.util.List<java.lang.String> 泛型類型:class java.lang.String #java.util.Map<java.lang.String, java.lang.Object> 泛型類型:class java.lang.String 泛型類型:class java.lang.Object 返回值,泛型類型:class java.lang.String
參考:http://my.oschina.net/u/2361475/blog/597726