反射的定義
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
自己的理解:
java會在編譯時將類的信息保存到堆中,反射便是獲取的編譯時保存的類的信息,反射不是該類的實例,反射更應該理解成類的圖 紙。通過這張圖紙可以獲取反射映射的類的所有信息,也可以通過這張圖紙創建一個實例。
//動態調用method Method method = stuClass.getDeclaredMethod("setName", String.class); method.invoke(stu1, "Lee");
通過動態調用的方式可以使得程式更為的靈活,如果想要調用私有的方法和屬性可以通過setAccessible來關閉安全檢測。
反射的效率
package com.lee.myTest; public class Student { private int id; private String name; private int age; //默認構造方法一定得有 public Student(){ } public Student(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } 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; } }
package com.lee.myTest; import java.lang.reflect.Method; public class TestReflex { //通過普通調用執行 public static void test01(){ Student student = new Student(); long startTime = System.currentTimeMillis(); for(int i = 0;i < 1000000000;i++) { student.getAge(); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"ms"); } //通過反射執行 public static void test02(){ try { //通過反射獲取實例 Class c = (Class) Class.forName("com.lee.myTest.Student"); Student stu = c.newInstance(); Method m = c.getDeclaredMethod("getId"); long startTime = System.currentTimeMillis(); for(int i = 0; i < 1000000000;i++) { m.invoke(stu); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"ms"); } catch (Exception e) { e.printStackTrace(); } } //通過反射執行(關閉安全檢查) public static void test03(){ try { //通過反射獲取實例 Class c = (Class) Class.forName("com.lee.myTest.Student"); Student stu = c.newInstance(); Method m = c.getDeclaredMethod("getId"); m.setAccessible(true);//關閉安全檢查 long startTime = System.currentTimeMillis(); for(int i = 0; i < 1000000000;i++) { m.invoke(stu); } long endTime = System.currentTimeMillis(); System.out.println(endTime-startTime+"ms"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { test01(); test02(); test03(); } }
對於不同的電腦可能會有不同的結果,setAccessible為true可以提高反射的運行效率,並且可以訪問到被private修飾的變量。