Java的反射

Java反射

Java獲取反射的三種方式

  • Java 中的反射首先是可以獲取到 Java 中要反射類的字節碼 。
  1. 經過new對象實現反射機制java

    //方式一(經過創建對象)
    Student student = new Student();
    Class classobj1 = student.getClass();
    System.out.println(classobj1.getName());
  2. 經過路徑實現反射機制數組

    //方式二(所在經過路徑-相對路徑)
    Class classobj1 = Class.forName("com.base.Student");
    System.out.println(classobj1.getName());
  3. 經過類名實現反射機制函數

    //方式三(經過類名)
    Class classobj1 = Student.class;
    System.out.println(classobj1.getName());

Java反射機制

  • Java 反射機制是在運行狀態中,對於任意一個類,都可以得到這個類的全部屬性和方法,對於任意一個對象都可以調用它的任意一個屬性和方法。這種在運行時動態的獲取信息以及動態調用對象的方法的功能稱爲 Java 的反射機制。spa

  • Class類與 java.lang.reflect 類庫一塊兒對反射的概念進行了支持,該類庫包括了FieldMethodConstructor類 (每一個類都實現了 Member接口)。這些類型的對象時由 JVM 在運行時建立的,用以表示未知類裏對應的成員。這樣你就能夠使用 Constructor 經過newInstance()建立新的對象,用invoke()方法調用與Method對象關聯的方法。另外,還能夠調用getFields() getMethod()getConstructor() 等很便利的方法,以返回表示字段,方法,以及構造器的對象的數組。這樣匿名對象的信息就能在運行時被徹底肯定下來,而在編譯時不須要知道任何事情。code

    package com.base.entity;
    public class Student {
        public String name;
        public int age;
        private String mobile;
        public Student() {
            System.out.println("無參構造函數被調用");
        }
        public Student(String type) {
            System.out.println("有參構造函數被調用 +" + type);
        }
        public void study(){
            System.out.println("study無參方法被調用");
        }
        public void study(String type){
            System.out.println("study有參方法被調用 + " + type);
        }
    }
    /****************************************************/
    package com.base.reflect;
    import com.base.entity.Student;
    import java.lang.reflect.Constructor;
    public class ReflectTest {
        public static void main(String[] args) throws Exception {
            Class aClass = Class.forName("com.base.entity.Student");
            //無參初始化
            Constructor<Student> constructors = aClass.getConstructor();
            Student student = constructors.newInstance();
            //有參初始化
            Constructor<Student> constructors1 = aClass.getConstructor(String.class);
            Student student1 = constructors1.newInstance("哈哈哈");
            //方法調用
            //有參方法調用
            Method study = aClass.getMethod("study", String.class);
            study.invoke(student,"我是好人");
            //無參方法調用
            Method study1 = aClass.getMethod("study");
            study1.invoke(student);
            //獲取類的屬性,沒法獲取私有化的屬性
            Field[] fields = aClass.getFields();
            System.out.println("獲取到Student類的屬性");
            for (Field field : fields) {
                System.out.print(" " + field.getName());
            }
            //獲取類的私有屬性
            Field mobile = aClass.getDeclaredField("mobile");
            mobile.setAccessible(true);
            Object o = mobile.get(student);
            System.out.println(o);
            mobile.set(student,"key");
            Object o1 = mobile.get(student);
            System.out.println(o1);
        }
    }

reflect類庫

  • Constructor:構造器對象

    class.getConstructor(Class<?>... parameterTypes);//獲取該類下非私有構造器(根據parameterTypes參數類型返回)
    class.getConstructors();//獲取該類非私有的全部構造器
    
    class.getDeclaredConstructor(Class<?>... parameterTypes);//獲取該類下構造器(根據parameterTypes參數類型返回)
    class.getDeclaredConstructors();//獲取該類的全部構造器
    //初始化
    constructor.newInstance(Object ... initargs);//有參數的構造器須要傳入對應類型的initargs
  • Method:方法接口

    class.getMethod(String name, Class<?>... parameterTypes);//獲取該類下非私有的name方法,(根據parameterTypes參數類型返回)
    class.getMethods();//獲取該類下的全部非私有方法
    class.getDeclaredMethod(String name, Class<?>... parameterTypes);//獲取該類下的name方法(根據parameterTypes參數類型返回)
    class.getDeclaredMethods();//獲取該類下的全部方法
    //調用方法
    method.invoke(Object obj);//參數爲此類的實體對象
  • Filed:屬性get

    aClass.getField(String name);//獲取該類下非私有的name屬性。
    aClass.getFields();//獲取該類下非私有的全部屬性
    aClass.getDeclaredField(String name);//獲取該類下的name屬性
    aClass.getDeclaredFields();//獲取該類下的全部屬性
    //get/set
    filed.get(Object obj);//獲取參數的值,參數爲此類的實例化對象
    filed.set(Object obj, Object value)//設置參數的值爲value
  • 注意:it

    • 此上全部經過Declared獲取到的私有構造器、方法、屬性調用時需先setAccessible(true)設置爲可訪問io

    • 靜態方法與靜態屬性的實體對象能夠不用傳遞。(如method.invoke(null);,filed.get(null);

相關文章
相關標籤/搜索