Java 反射

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

[TOC]數組

反射機制的相關類ide

與Java反射相關的類以下:this

類名 用途
Class類 表明類的實體,在運行的Java應用程序中表示類和接口
Field類 表明類的成員變量(成員變量也稱爲類的屬性)
Method類 表明類的方法
Constructor類 表明類的構造方法

Class類

Class表明類的實體,在運行的Java應用程序中表示類和接口。在這個類中提供了不少有用的方法,這裏對他們簡單的分類介紹。代理

得到類相關的方法

方法 用途
asSubclass(Class<U> clazz) 把傳遞的類的對象轉換成表明其子類的對象
Cast 把對象轉換成表明類或是接口的對象
getClassLoader() 得到類的加載器
getClasses() 返回一個數組,數組中包含該類中全部公共類和接口類的對象
getDeclaredClasses() 返回一個數組,數組中包含該類中全部類和接口類的對象
forName(String className) 根據類名返回類的對象
getName() 得到類的完整路徑名字
newInstance() 建立類的實例
getPackage() 得到類的包
getSimpleName() 得到類的名字
getSuperclass() 得到當前類繼承的父類的名字
getInterfaces() 得到當前類實現的類或是接口

得到類中屬性相關的方法

方法 用途
getField(String name) 得到某個公有的屬性對象
getFields() 得到全部公有的屬性對象
getDeclaredField(String name) 得到某個屬性對象
getDeclaredFields() 得到全部屬性對象

得到類中註解相關的方法

方法 用途
getAnnotation(Class annotationClass) 返回該類中與參數類型匹配的公有註解對象
getAnnotations() 返回該類全部的公有註解對象
getDeclaredAnnotation(Class annotationClass) 返回該類中與參數類型匹配的全部註解對象
getDeclaredAnnotations() 返回該類全部的註解對象

得到類中構造器相關的方法

方法 用途
getConstructor(Class...<?> parameterTypes) 得到該類中與參數類型匹配的公有構造方法
getConstructors() 得到該類的全部公有構造方法
getDeclaredConstructor(Class...<?> parameterTypes) 得到該類中與參數類型匹配的構造方法
getDeclaredConstructors() 得到該類全部構造方法

得到類中方法相關的方法

方法 用途
getMethod(String name, Class...<?> parameterTypes) 得到該類某個公有的方法
getMethods() 得到該類全部公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes) 得到該類某個方法
getDeclaredMethods() 得到該類全部方法

類中其餘重要的方法

方法 用途
isAnnotation() 若是是註解類型則返回true
isAnnotationPresent(Class<? extends Annotation> annotationClass) 若是是指定類型註解類型則返回true
isAnonymousClass() 若是是匿名類則返回true
isArray() 若是是一個數組類則返回true
isEnum() 若是是枚舉類則返回true
isInstance(Object obj) 若是obj是該類的實例則返回true
isInterface() 若是是接口類則返回true
isLocalClass() 若是是局部類則返回true
isMemberClass() 若是是內部類則返回true

Field類

Field表明類的成員變量(成員變量也稱爲類的屬性)。code

方法 用途
equals(Object obj) 屬性與obj相等則返回true
get(Object obj) 得到obj中對應的屬性值
set(Object obj, Object value) 設置obj中對應屬性值

Method類

Method表明類的方法。對象

方法 用途
invoke(Object obj, Object... args) 傳遞object對象及參數調用該對象對應的方法

Constructor類

Constructor表明類的構造方法。繼承

方法 用途
newInstance(Object... initargs) 根據傳遞的參數建立類的對象

示例:接口

沒反射以前建立

Person p = new Person();
        p.setAge("1");
        p.setName("zs");
        p.setSex("0");

        p.show();
        p.display("china");

使用反射 獲取運行時類的信息

  • 1 經過反射建立對象
//Class<T>  這裏可使用泛型
        Class clazz = Person.class;
        Person person = (Person) clazz.newInstance();
        person.setSex("1");
        ;
        person.setName("zs2");
        person.setAge("2");
        person.show();
        person.display("Keroar");
  • 2 經過反射設置對象屬性的指定屬性

使用反射動態的設置get

Person person2 = (Person) clazz.newInstance();
        //這種這隻屬性只能是public修飾的
        Field field = clazz.getField("name");
        field.set(person2, " 我是名字 ");
        System.out.println(person2);

        //private 或者 其餘的須要設置訪問權限
        Field field1 = clazz.getDeclaredField("sex");
        field1.setAccessible(true);
        field1.set(person2, "我是sex");
        System.out.println(person2);
  • 3 經過反射獲取指定類的指定方法屬性

    獲取方法 根據方法名 以及 parameterTypes 可變參數類型,沒有參數就不寫了
public Method getMethod(String name, Class<?>... parameterTypes)
1 獲取設置除public修飾的
        //調用傳參方法 display
        Method method = clazz.getMethod("show");
        method.invoke(person2);

        //2 一樣 設置除public 以外的訪問
        //public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        // method.setAccessible(true);


        //獲取方法上註解以及方法參數類型 返回類型 方法名
        System.out.println("方法名 : " + method.getName());
        System.out.println("參數類型 : " + method.getTypeParameters());
        System.out.println("返回類型 : " + method.getReturnType());
        //System.out.println("返回全部註解 : " + method.getAnnotations());
        //System.out.println("返回全部參數註解 : " + method.getParameterAnnotations());
        System.out.println("返回方法參數註解 : " + method.getAnnotation(clazz));

        //調用方法
        //public Object invoke(Object obj, Object... args)  obj 調用的對象,args 傳入方法可變參數


        //調用傳參方法 display
        Method methods = clazz.getMethod("display", String.class);
        methods.invoke(person2, "我是傳入的國籍參數");

Class<T> 反射的源頭

  • 每個運行類只加載一次
    有了Class 實例才能進行

    1 建立對象
                                2 獲取類中全部的屬性 方法 父類 內部類 構造 異常 等等...
                                3 調用屬性和方法等
                                4 反射的應用 : 動態代理
經過調用 getClass , 獲取 Person 類運行時類的calss對象
Class pClass = p.getClass();
        System.out.println(pClass);

建立Class 四種方法

//1 經過運行類對象調用 getClass 方法
        //2 調用自己.class 屬性
        Class clazz1 = Person.class;
        Class  clazz2  = String.class;
        // 3 經過Class 靜態方法獲取
        Class<?> aClass = Class.forName("reflection.Person");
        System.out.println(aClass);


        // 4 類的加載器
        ClassLoader classLoader = this.getClass().getClassLoader();
        Class<?> aClass1 = classLoader.loadClass("reflection.Person");
        System.out.println(aClass1);

類加載器做用

除了加載類以外類加載器能夠用來幹嗎?

加載屬性文件

//1 
        ClassLoader classLoader = aClass.getClassLoader();
        // 加載類
        // classLoader.loadClass();

        //例如讀取jdbc 配置文件
         String name = "jdbc.properties";
        InputStream resourceAsStream = classLoader.getResourceAsStream(name);
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String property = properties.getProperty("key");
package reflection;

public class Person {

    public String name;
    private String age;
    private String sex; // 0 男  1 女

    public Person(String name, String age, String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public Person(){
    }

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public void show(){
        System.out.println("  emmmmmmm  ");
    }


    public void display(String contry){
        System.out.println("  個人國籍是   " +  contry);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
相關文章
相關標籤/搜索