關於java反射的使用

反射的定義

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修飾的變量。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *