Java反射是什麼?如何通過反射獲取類信息

1.java反射的概念

       JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。通俗的講就是反射可以在運行時根據指定的類名獲得類的信息。

2.反射的作用

首先我們先明確兩個概念,靜態編譯和動態編譯。

靜態編譯:在編譯時確定類型,綁定對象,即通過。 
          動態編譯:運行時確定類型,綁定對象。動態編譯最大限度發揮了java的靈活性,體現了多態的應用,有以降低類之間的藕合性。我們可以明確的看出動態編譯的好處,而反射就是運用了動態編譯創建對象。

在我們創建數據庫鏈接時,這句代碼Class tc = Class.forName("com.java.dbtest.TestConnection")就是告訴JVM去加載這個類,而加載的過程是在程序執行過程中動態加載的。通過類的全類名讓jvm在服務器中找到並加載這個類,而如果是使用別的數據庫,那就要換一個類了,如果是傳統寫死的方法創建,就要修改原來類的代碼,而對於反射,則只是傳入的參數就變成另一個了而已,可以通過修改配置文件,而不是直接修改代碼。

在框架設計中常常用到反射機制,比如在spring中,我們將所有的類Bean交給spring容器管理,無論是XML配置Bean還是註解配置,當我們從容器中獲取Bean來依賴注入時,容器會讀取配置,而配置中給的就是類的信息,spring根據這些信息,需要創建那些Bean,spring就動態的創建這些類

簡單來理解,使用反射能有效減低代碼耦合。

3.反射的原理

JAVA語言編譯之後會生成一個.class文件,反射就是通過字節碼文件找到某一個類、類中的方法以及屬性等,具體如何實現就先不管

4.反射的使用

直接上代碼

package com.reflex;
/**
 * 
 * 類名稱: Student   
 * 類描述:                
 * 創建人: zzh         
 * 修改時間:2018年9月10日 下午2:40:12 
 * 修改備註:
 * @version 1.0.0
 */
public class Student{
	
    private int age;
    public String name;
 
    public Student(){}
 
    public Student(String name,int age){
    	this.name=name;
        this.age=age;
    }
 
    public String test1(){
        return "test1";
    }
    public String test2(){
        return "test2";
    }

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}
    
    
 
}

package com.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ClassReflexUtil {
	
	private Class c;
	
	public ClassReflexUtil() {
	}
	 
	public ClassReflexUtil(String className) throws ClassNotFoundException {
		//1.獲取Class對象
		 c = Class.forName(className);
	}

	//獲取構造函數的所有內容
	private void getConstruction() {
		System.out.println("************構造函數的所有內容(包括私有、受保護、默認的)********************");
		Constructor[] constructors=c.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.print(Modifier.toString(constructor.getModifiers())+" ");//獲取構造函數的修飾符
            System.out.print(constructor.getName()+"(");  //獲取構造函數的名稱
            Class[] p=constructor.getParameterTypes();
            for(int k=0;k<p.length;k++){
                System.out.print(p[k].getName()+" ");
            }
            System.out.println(" );");
        }
		
	}
	//獲取相應類的所有屬性
    public  void getParameter() throws ClassNotFoundException{
		//獲取屬性
		
		System.out.println("************獲取所有的字段(包括私有、受保護、默認的)********************");
		Field[] fieldArray = c.getDeclaredFields();
		for(Field f : fieldArray){
			System.out.println(f);
		}
		
		/*
		System.out.println("************獲取所有公有的字段********************");
		Field[] fieldArray = stuClass.getFi elds();
		for(Field f : fieldArray){
			System.out.println(f);
		}*/
    }
    
    //獲取相應類裏面的所有申明的方法
    private void getDeclaredFields() {
    	System.out.println("************獲取所有的方法(包括私有、受保護、默認的)********************");
    	 Method field[]=c.getDeclaredMethods();
         for (Method method : field) {
             System.out.print(Modifier.toString(method.getModifiers())+" "); //獲取函數的修飾符權限
             System.out.print(method.getReturnType()+" "+method.getName()+"("); //獲取函數的名稱
             Class type[]= method.getParameterTypes();
             for (Class aClass : type) {
                 System.out.print(aClass.getName()+" ");
             }
             System.out.println(");");
         }
		
	}
    //設置相應類的屬性值
    public  void setParameter(String  parameter,String value) throws  NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException{
    	Field field=c.getField(parameter);
    	System.out.println(field);
		//獲取一個對象
		Object obj = c.getConstructor().newInstance();
		//爲字段設置值
		field.set(obj, value);
		//驗證
		 
		Student stu = (Student)obj;
		System.out.println("驗證姓名:" + stu.name);

    }


    public static void main(String[] args) throws Exception {
		ClassReflexUtil cReflexUtil=new ClassReflexUtil("com.reflex.Student");
		cReflexUtil.getParameter();
		cReflexUtil.getConstruction();
		cReflexUtil.getDeclaredFields();
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章