java反射基礎鞏固

        反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性,這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。一直以來反射技術都是Java中的閃亮點,這也是目前大部分框架(如Spring/Mybatis等)得以實現的支柱。

        在Java中,Class類與java.lang.reflect類庫一起對反射技術進行了全力的支持。在反射包中,我們常用的類主要有Constructor類表示的是Class 對象所表示的類的構造方法,利用它可以在運行時動態創建對象、Field表示Class對象所表示的類的成員變量,通過它可以在運行時動態修改成員變量的屬性值(包含private)、Method表示Class對象所表示的類的成員方法,通過它可以動態調用對象的方法(包含private)

一、實體對象類,用作反射操作的對象

public class Person  {

    public static final long serialVersionUID=1l;
    public  String name;
    private  int age;

    public Person() {
        System.out.println("無參構造函數,運行...");
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造函數,運行...");
        System.out.println("name:"+this.name+",age:"+this.age);

    }

    public void method01(){
        System.out.println("共有無參函數,運行...");
    }
    private void method02(){
        System.out.println("私有無參函數,運行...");
    }
    public void method03(String name,int age){
        System.out.println("公有帶參函數,name:"+name+"; age:"+age);
    }
    private void method04(String name,int age){
        System.out.println("私有帶參函數,name:"+name+"; age:"+age);
    }

}

二、獲取字節碼類的方式

/**
     * @Author Loujitao
     * @Date 2018/6/27
     * @Time  11:32
     * @Description: 第一種通過實例對象獲取字節碼類   
     */
    public  static  void function01(){
        Person person=new Person();
        Class c=person.getClass();
        System.out.println(c);
        /**結果:
        *   無參構造函數,運行...
        *   class com.steve.reflect.Person
        */
    }

    public  static  void function02(){
        //通過靜態方法獲取字節碼類
        Class c=Person.class;
        System.out.println(c);
        /**結果:
        *   class com.steve.reflect.Person
        */
    }

    public  static  void function03() throws Exception{
        //通過類名獲取字節碼類  
        Class c  = Class.forName("com.steve.reflect.Person");
        System.out.println(c);
        /**結果:
        *   class com.steve.reflect.Person
        */
    }

三、獲取字段(成員變量)

/**
     * 獲取單個字段
     */
    public static void  function01(Class c) throws Exception{
        //它反映此 Class 對象所表示的類或接口的指定   公共  成員字段。
        Field field=c.getField("name");
        //反映此 Class 對象所表示的類或接口的指定已聲明字段。   可以獲取私有的屬性
        Field f=c.getDeclaredField("age");

        System.out.println("name:     "+field );
        System.out.println("age:      "+f);
       /* 結果:
          name:     public java.lang.String com.steve.reflect.Person.name
          age:      private int com.steve.reflect.Person.age
        */
    }

 /*
     * 獲取字段數組 只能獲取共有的字段
     * */
    public  static  void function02(Class c) throws Exception{

        Field[] fields=c.getFields();
        for (Field f:fields ) {
            System.out.println(f);
        }
       /**結果:
        *    public static final long com.steve.reflect.Person.serialVersionUID
        *    public java.lang.String com.steve.reflect.Person.name
        */
    }

 /*
     * 獲取字段數組 所有的
     * */
    public static void function03(Class c)throws Exception{
        Field[] fields=c.getDeclaredFields();
        for (Field f:fields ) {
            System.out.println(f);
        }
        /**結果:
         *  public static final long com.steve.reflect.Person.serialVersionUID
            public java.lang.String com.steve.reflect.Person.name
            private int com.steve.reflect.Person.age
         * */
    }

四、獲取方法並執行

//獲取構造函數
    public  static void function01(Class c) throws Exception{
        Object obj=c.newInstance();
        System.out.println(obj);

        Constructor ct=c.getConstructor(String.class,int.class);
        Object o= ct.newInstance("steve",18);
        System.out.println(o);
     /*結果:
        無參構造函數,運行...
        com.steve.reflect.Person@1540e19d
        有參構造函數,運行...
        name:steve,age:18
        com.steve.reflect.Person@677327b6
        */
    }
    //獲取方法
    public  static void function02(Class c)throws Exception{
        Object obj=c.newInstance();
        Method m=c.getMethod("method01",null);
        m.invoke(obj);

        Method m2=c.getDeclaredMethod("method02",null);
        //將反射的對象標記爲在使用時取消默認 Java 語言訪問控制檢查的能力
        m2.setAccessible(true);
        //對帶有指定參數的指定對象調用由此 Method 對象表示的底層方法。
        m2.invoke(obj);

        Method m3=c.getMethod("method03",String.class,int.class);
        m3.invoke(obj,"steve",26);

        Method m4=c.getDeclaredMethod("method04",String.class,int.class);
        m4.setAccessible(true);
        m4.invoke(obj,"steve",26);
    }
    //獲取方法數組
    public  static void function03(Class c)throws Exception{
        //獲取共有方法
        Method[] m1=c.getMethods();
        for (Method m:m1) {
            System.out.println(m);
        }
        System.out.println("----------手動分割線-------------------");
        Method[] m2=c.getDeclaredMethods();
        for (Method mt:m2 ) {
            System.out.println(mt);
        }
    }


發佈了76 篇原創文章 · 獲贊 46 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章