Java 反射機制

什麼是反射

在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。java

Class類

獲取Class對象的方式:git

  1. 調用Object類的getClass()方法來獲得Class對象,這也是最多見的產生Class對象的方法。例如:
    MyObject x;
    Class c1 = x.getClass();github

  2. 使用Class類的中靜態forName()方法得到與字符串對應的Class對象。例如:
    Class c2=Class.forName(「類名或接口名」);函數

  3. 若是T是一個Java類型,那麼T.class就表明了匹配的類對象。例如:
    Class cl1 = Manager.class;
    Class cl2 = int.class;
    Class cl3 = Double[].class;
  4. 經過類加載器獲取類對象,例如:
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    Class cl1 = loader.loadClass("類名");this

Class類的重要方法以下:code

  1. 獲取類名
    • String getName()
  2. 獲取Class對象
    • static Class<?> forName(String className)
  3. 獲取類加載器
    • ClassLoader getClassLoader()
  4. 建立類的實例
    • T newInstance()
  5. 獲取反射類對象
    1. 獲取構造函數反射類
      • Constructor getConstructor(Class<?>... parameterTypes)
      • Constructor<?>[] getConstructors()
      • Constructor getDeclaredConstructor(Class<?>... parameterTypes)
      • Constructor<?>[] getDeclaredConstructors()
    2. 獲取類方法的反射類
      • Method getMethod(String name, Class<?>... parameterTypes)
      • Method[] getMethods()
      • Method getDeclaredMethod(String name, Class<?>... parameterTypes)
      • Method[] getDeclaredMethods()
    3. 獲取類成員變量的反射類
      • Field getField(String name)
      • Field[] getFields()
      • Field getDeclaredField(String name)
      • Field[] getDeclaredFields()
  • 注意:getXXX()和getDeclaredXXX()的區別是,getXXX()只能獲取public的反射類對象,getDeclaredXXX()則沒有限制。

反射類

反射類經過Class類對象來獲取,主要包括構造函數、成員變量、類方法,經過反射類對象能夠實例化目標類、調用目標類對象的方法、操做目標類對象的域。對象

  1. java.lang.reflect.Constructor
    使用newInstance()方法實例化目標類,注意Class類的newInstance()方法只能調用默認無參構造函數,使用Constructor的newInstance()方法能夠帶參。
    • T newInstance(Object... initargs)
  2. java.lang.reflect.Method
    Method對象最重要的方法就是invoke(),至關於調用實例的方法:
    • Object invoke(Object obj, Object... args)
  3. java.lang.reflect.Field
    Field方法最主要的方法是set():
    • void set(Object obj, Object value)
    • void setXXX(Object obj, XXX z)

一個例子

https://github.com/kaname233/SpringLearn/tree/master/src/top/sunjing98/reflect
一個普通的Java類Student:
接口


展開查看

package top.sunjing98.reflect;
public class Student {
    private String stuName;
    private int stuAge;

    public Student() {
    }

    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }

    public void introduce() {
        System.out.println("stuName: " + stuName + " stuAge: " + stuAge);
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public int getStuAge() {
        return stuAge;
    }

    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }
}

經過反射機制建立並操做目標類對象:字符串

package top.sunjing98.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectTest {
    public static Student initByDefaultConst() throws Throwable {
        //一、經過類裝載器獲取類對象
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class clazz = loader.loadClass("top.sunjing98.reflect.Student");
        //二、經過類對象獲取構造器對象,經過構造器對象實例化類
        Constructor constructor = clazz.getDeclaredConstructor( null);
        Student s = (Student) constructor.newInstance();
        //三、經過類對象獲取方法對象,經過反射方法設置屬性
        Method setStuName = clazz.getMethod("setStuName", String.class);
        Method setStuAge = clazz.getMethod("setStuAge", int.class);
        setStuName.invoke(s, "張三");
        setStuAge.invoke(s, 23);
        return s;
    }

    public static void main(String[] args) throws Throwable {
        Student s = initByDefaultConst();
        s.introduce();
    }
}

輸出:get

stuName: 張三 stuAge: 23
相關文章
相關標籤/搜索