Java反射實踐

一骡男、概述

Java的反射機(jī)制是Java語言動態(tài)性的一種體現(xiàn)芭析。反射機(jī)制是通過反射API來實現(xiàn)的窗悯,它允許程序在運行過程中(runtime)取得任何一個已知名稱類的內(nèi)部信息瓶逃,包括其中的構(gòu)造方法、聲明的字段和定義的方法等丽已。這不得不說是一個很強大的能力蚌堵。

二、基本方法

說到反射的用法不得不提java.lang.Class類沛婴,通過該類的對象就的方法可以獲取到該類中的構(gòu)造方法吼畏、域和方法。對應(yīng)的方法分別是getConstructor嘁灯、getField和getMethod泻蚊。這三個方法還有相應(yīng)的getDeclaredXXX版本,區(qū)別在于getDeclaredXXX版本的方法會獲取該類自身所聲明的所有字段包括public, protected, default (package), 和 private丑婿,但不會獲取繼承下來的字段性雄。

Java反射API位于java.lang.reflect包中没卸。主要包括以下幾類:

  • 1.Constructor類:用來描述一個類的構(gòu)造方法。
  • 2.Field類:用來描述一個類的成員變量秒旋。
  • 3.Method類:用來描述一個類的方法约计。
  • 4.Modifer類:用來描述類內(nèi)各元素的修飾符。
  • 5.Array:用來對數(shù)組進(jìn)行操作迁筛。
    Constructor煤蚌、Field和Method這三個類分別表示類中的構(gòu)造方法、字段和方法细卧。
三尉桩、獲取類的構(gòu)造方法

java.lang.Class提供了4種獲取類構(gòu)造方法的反射調(diào)用:

  • Constructor getConstructor(Class[] params) -通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法;
  • Constructor[] getConstructors() -獲得類的所有公共構(gòu)造函數(shù)贪庙;
  • Constructor getDeclaredConstructor(Class[] params) -獲得使用特定參數(shù)類型的構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法)蜘犁;
  • Constructor[] getDeclaredConstructors() -獲得類的所有構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法);
    調(diào)用這些方法會返回一個或多個 java.lang.reflect.Constructor 對象插勤。Constructor 類定義了newInstance 方法沽瘦,它采用一組對象作為其唯一的參數(shù)革骨,然后返回新創(chuàng)建的原始類實例农尖。該組對象是用于構(gòu)造函數(shù)調(diào)用的參數(shù)值。
3.1 獲取類的Class對象

方式一:通過將目標(biāo)類裝入到虛擬機(jī)的方式獲得該類的Class對象;

Class<?> cls=Class.forName("java.lang.String");

方式二:通過類或類的對象獲取類的Class對象;

Class<?> cls=String.class;

String str="";
Class<?> cls=str.getClass()
Class<?> cls=Class.forName("java.lang.String");

3.2 根據(jù)需要調(diào)用Class對象的4種獲取構(gòu)造方法的一種良哲,獲取到類的構(gòu)造方法
  • 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法;
  try {
            Class<?> aClass = Class.forName("java.lang.String");
            //1.獲取里面有特殊參數(shù)類型的公共構(gòu)造方法
            Class[] parameterTypes = {String.class};
            System.out.println("1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法");
            Constructor<?> constructor = aClass.getConstructor(parameterTypes);
            System.out.println("1---->constructor:"+constructor.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法
         * 1---->constructor:public java.lang.String(java.lang.String)
         */
  • 2.通過指定構(gòu)造參數(shù)獲取類的指定構(gòu)造方法,不是public的也會得到(不包含繼承的構(gòu)造方法)
      try {
            Class<?> aClass = Class.forName("java.lang.String");
            Class[] parameterTypes = {char[].class, boolean.class};
            System.out.println("2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法盛卡,該構(gòu)造方法不是繼承的");
            Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(parameterTypes);
            System.out.println("2---->declaredConstructor:"+declaredConstructor.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
       /**
         * 打印結(jié)果:
         *2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法,該構(gòu)造方法不是繼承的
         *2---->declaredConstructor:java.lang.String(char[],boolean)
         */
  • 3.獲取所有的公共構(gòu)造方法
 String str = "";
        Class<? extends String> aClass = str.getClass();
        System.out.println("3.獲取所有的公共構(gòu)造方法:");
        Constructor<?>[] constructors = aClass.getConstructors();
        for (int i = 0 ;i<constructors.length;i++) {
            System.out.println("總共:"+constructors.length+"筑凫,當(dāng)前第"+(i+1)+"個"+constructors[i].toString());
        }
        /**
         * 打印結(jié)果如下:
         * 3.獲取所有的公共構(gòu)造方法:
         總共:15滑沧,當(dāng)前第1個public java.lang.String(byte[],int,int)
         總共:15,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
         總共:15巍实,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
         總共:15滓技,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
         總共:15,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
         總共:15棚潦,當(dāng)前第6個public java.lang.String(java.lang.StringBuilder)
         總共:15令漂,當(dāng)前第7個public java.lang.String(java.lang.StringBuffer)
         總共:15,當(dāng)前第8個public java.lang.String(byte[])
         總共:15丸边,當(dāng)前第9個public java.lang.String(int[],int,int)
         總共:15叠必,當(dāng)前第10個public java.lang.String()
         總共:15,當(dāng)前第11個public java.lang.String(char[])
         總共:15妹窖,當(dāng)前第12個public java.lang.String(java.lang.String)
         總共:15纬朝,當(dāng)前第13個public java.lang.String(char[],int,int)
         總共:15,當(dāng)前第14個public java.lang.String(byte[],int)
         總共:15骄呼,當(dāng)前第15個public java.lang.String(byte[],int,int,int)
         * 
         */
  • 4.獲取所有類的構(gòu)造方法(不包含繼承的)
 Class<String> stringClass = String.class;
        System.out.println("4.獲取所有的構(gòu)造方法共苛,不包含繼承的");
        Constructor<?>[] declaredConstructors = stringClass.getDeclaredConstructors();
        for (int i = 0 ;i<declaredConstructors.length;i++) {
            System.out.println("總共:"+declaredConstructors.length+"判没,當(dāng)前第"+(i+1)+"個"+declaredConstructors[i].toString());
        }
        /**
         * 打印結(jié)果如下:
         *4.獲取所有的構(gòu)造方法,不包含繼承的
         總共:16隅茎,當(dāng)前第1個public java.lang.String(byte[],int,int)
         總共:16哆致,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
         總共:16,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
         總共:16患膛,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
         總共:16摊阀,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
         總共:16,當(dāng)前第6個java.lang.String(char[],boolean)
         總共:16踪蹬,當(dāng)前第7個public java.lang.String(java.lang.StringBuilder)
         總共:16胞此,當(dāng)前第8個public java.lang.String(java.lang.StringBuffer)
         總共:16,當(dāng)前第9個public java.lang.String(byte[])
         總共:16跃捣,當(dāng)前第10個public java.lang.String(int[],int,int)
         總共:16漱牵,當(dāng)前第11個public java.lang.String()
         總共:16,當(dāng)前第12個public java.lang.String(char[])
         總共:16疚漆,當(dāng)前第13個public java.lang.String(java.lang.String)
         總共:16酣胀,當(dāng)前第14個public java.lang.String(char[],int,int)
         總共:16,當(dāng)前第15個public java.lang.String(byte[],int)
         總共:16娶聘,當(dāng)前第16個public java.lang.String(byte[],int,int,int)
         */
  • 5.獲取類默認(rèn)的構(gòu)造方法
     Class<String> stringClass = String.class;
        System.out.println("5.獲取類默認(rèn)的構(gòu)造方法");
        try {
            Constructor<String> constructor = stringClass.getConstructor();
            System.out.println("5---->默認(rèn)的構(gòu)造方法:"+constructor.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 5.獲取類默認(rèn)的構(gòu)造方法
         *5---->默認(rèn)的構(gòu)造方法:public java.lang.String()
         */
四闻镶、通過反射獲取類的實例

上文中已經(jīng)通過反射獲取到類的構(gòu)造方法也就是Constructor對象。Constructor對象提供了public T newInstance(Object ... initargs)方法丸升,該方法返回類的實例铆农,其中initargs作為調(diào)用類的構(gòu)造方法的參數(shù)數(shù)組,反射API會根據(jù)數(shù)組中元素的類型和個數(shù)選擇調(diào)用類的相應(yīng)構(gòu)造方法狡耻。

 Class<String> aClass = String.class;
        System.out.println("通過指定構(gòu)造方法中參數(shù)類型墩剖,來獲取指定的構(gòu)造方法");
        Class[] paramterType = {char[].class, boolean.class};
        try {
            Constructor<String> declaredConstructor = aClass.getDeclaredConstructor(paramterType);
            System.out.println("declaredConstructor----->"+declaredConstructor.toString());
            //告訴虛擬機(jī),當(dāng)調(diào)用該構(gòu)造方法時夷狰,不用進(jìn)行訪問權(quán)限的控制岭皂,也就是給反射開個綠燈;
            declaredConstructor.setAccessible(true);
            char[] chars = {'a',' ','s','t','u','d','e','n','t'};
            Object newInstance = declaredConstructor.newInstance(chars, false);
            System.out.println("-----object------->"+newInstance.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 通過指定構(gòu)造方法中參數(shù)類型,來獲取指定的構(gòu)造方法
         *declaredConstructor----->java.lang.String(char[],boolean)
         *-----object------->a student
         */

上面代碼中constructor2.setAccessible(true)的意思是告訴虛擬機(jī)沼头,當(dāng)調(diào)用該構(gòu)造方法時爷绘,不用進(jìn)行訪問權(quán)限的控制,也就是給反射開個綠燈瘫证。相應(yīng)地Method揉阎,F(xiàn)ield以及Constructor類都直接或間接的繼承了AccessibleObject類,該類提供了將反射的對象標(biāo)記為在使用時取消默認(rèn) Java 語言訪問控制檢查的能力背捌。所以說在使用Method毙籽,F(xiàn)ield以及Constructor類的對象時,如果該對象所表示的方法或字段是非public的毡庆,那么在訪問它之前需要調(diào)用 public void setAccessible(boolean flag)方法將該對象的訪問控制權(quán)限取消坑赡,否則java的異常處理機(jī)制會告訴你 can not access a member of class烙如。

五、通過反射獲取和修改類中的字段

和獲取類的構(gòu)造方法相似的是Class類同樣也提供了獲取類中字段的4種調(diào)用:

  • 1.Field getField(String name) – 獲得命名的公共字段毅否;
  • 2.Field[] getFields() – 獲得類的所有公共字段亚铁;
  • 3.Field getDeclaredField(String name) – 獲得類聲明的命名的字段;
  • 4.Field[] getDeclaredFields() – 獲得類聲明的所有字段螟加;
    同樣getField與getFields可以獲得當(dāng)前類中以及繼承的public字段徘溢,getDeclaredField與getDeclaredFields則可以獲得當(dāng)前類中聲明的所有字段,但不能獲取繼承的字段捆探。
    java.lang.reflect.Field表示類中的字段然爆,該類提供了getXXX 和 setXXX 方法,以及get 和 set 方法來獲取和設(shè)置該字段的值黍图。大家可以根據(jù)實際的字段類型自行選擇一種適當(dāng)?shù)姆椒ā?先看一下一會要用到的Person類曾雕,該類是一個簡單的JavaBean。
public class Person {
    public String sex ;
}


public class Student extends Person{
    private static int age ;
    private static int width ;
    private String name;
    private int height ;
     public static int getWidth() {
        return width;
    }

    public static void setWidth(int width) {
        Student.width = width;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    /**
     * 其他代碼省略
     */

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                '}';
    }
}
  • 5.1 獲取指定字段
 Student student = new Student();
        Class<? extends Student> aClass = student.getClass();
        System.out.println("獲取指定字段");
        try {
            Field field = aClass.getDeclaredField("height");
            field.setAccessible(true);
            field.set(student,20);
            System.out.println("----student--->"+student.toString());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * ----student--->Student{name='null', height=20}
         */
  • 5.2 獲取類的所有字段
    1.獲取該類以及繼承的所有公有字段;
 System.out.println("獲取該類及繼承的所有公有字段");
        Field[]fields=aClass.getFields();
        for (int i = 0; i < fields.length; i++) {
            System.out.println("總共:"+fields.length+"當(dāng)前第"+(i+1)+"個 "+fields[i].toString());
        }
        /**
         * 打印結(jié)果:
         * 獲取該類及繼承的所有公有字段
         * 總共:1當(dāng)前第1個 public java.lang.String com.zcbl_videosurvey.test.Person.sex
         */

2.獲取該類所有的字段

 System.out.println("獲取該類的所有字段助被,不包含繼承的");
        Field[]fields2=aClass.getDeclaredFields();
        for (int i = 0; i < fields2.length; i++) {
            System.out.println("總共:"+fields2.length+"當(dāng)前第"+(i+1)+"個 "+fields2[i].toString());
        }
        /**
         * 打印結(jié)果:
         *總共:3當(dāng)前第1個 private static int com.zcbl_videosurvey.test.Student.age
         *總共:3當(dāng)前第2個 private java.lang.String com.zcbl_videosurvey.test.Student.name
         *總共:3當(dāng)前第3個 private int com.zcbl_videosurvey.test.Student.height
         */
需改字段

修非靜態(tài)字段
非靜態(tài)字段和方法屬于類的對象所有剖张,所以要修改類的非靜態(tài)字段需要一個該類的對象。

 Student student = new Student();
        Class<? extends Student> aClass = student.getClass();
        System.out.println("獲取指定字段");
        try {
            Field field = aClass.getDeclaredField("height");
            field.setAccessible(true);
            field.set(student,20);
            System.out.println("----student--->"+student.toString());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * ----student--->Student{name='null', height=20}
         */

需要指出的是如果字段是非public的揩环,需要在訪問該字段前取消該字段的訪問權(quán)限控制field.setAccessible(true)搔弄,那么對于一個final字段是否可以通過反射修改它的值呢,答案是肯定的检盼,前提同樣是在訪問該字段前取消該字段的訪問權(quán)限控制肯污。但如果該字段既被final修飾又被static修飾翘单,那么是無法修改的吨枉。

修改靜態(tài)字段
和修改非靜態(tài)字段相比,修改類的靜態(tài)字段就要輕松的多了哄芜,因為靜態(tài)字段屬于類所有貌亭,所以在修改靜態(tài)字段的時候就不需要再傳遞一個該類的對象了。

  System.out.println("修改靜態(tài)字段");
        try {
            Field field = aClass.getDeclaredField("age");
            field.setAccessible(true);
            field.set(null,180);
            System.out.println("-------->"+field.get(null));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 修改靜態(tài)字段
         *-------->180
         */
六认臊、通過反射獲取并調(diào)用類中的方法

Class類提供了以下4種方式來獲取類中的方法:

  • 1.Method getMethod(String name, Class[] params) – 使用特定的參數(shù)類型圃庭,獲得命名的公共方法;
  • 2.Method[] getMethods() – 獲得類的所有公共方法失晴;
  • 3.Method getDeclaredMethod(String name, Class[] params) – 使用特寫的參數(shù)類型剧腻,獲得類聲明的命名的方法;
  • 4.Method[] getDeclaredMethods() – 獲得類聲明的所有方法涂屁;
    與獲取類中字段類似书在,前兩個方法用于獲取類中以及繼承的所有公共方法 。后兩個方法用于獲取當(dāng)前類中(不包含繼承)所有的方法拆又。以上4種方法返回的是Method對象儒旬,Method類中提供了public Object invoke(Object obj, Object... args)通過該方法我們可以調(diào)用任何一個類的任何一個方法栏账。invoke 方法使用兩個參數(shù),為調(diào)用提供類實例和參數(shù)值數(shù)組栈源。
6.1 調(diào)用非靜態(tài)方法

Method類中提供了public Object invoke(Object obj, Object... args)通過該方法我們可以調(diào)用任何一個類的任何一個方法挡爵。invoke 方法使用兩個參數(shù),為調(diào)用提供類實例和參數(shù)值數(shù)組甚垦。如果第二個參數(shù)沒有茶鹃,可以省略或者null或者new Object[0];

 Student student = new Student();
        Class aClass = student.getClass();
        try {
            Method method = aClass.getMethod("setName", new Class[]{String.class});
            method.invoke(student, "wanglu");
            Method method1 = aClass.getMethod("getName", new Class[]{});
            //第二個參數(shù)代表的參數(shù)數(shù)組值艰亮,如果沒有可以省略或者null或者new Object[0]
            Object invoke = method1.invoke(student);
            System.out.println("-------getName------>"+invoke.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * -------getName------>wanglu
         */
6.2 調(diào)用靜態(tài)方法
 Student student = new Student();
        Class<? extends Student> aClass = student.getClass();
        try {
            Method method = aClass.getMethod("setAge", new Class[]{int.class});;
            method.invoke(student, 20);

            Method method1 = aClass.getMethod("getAge", new Class[]{});
            Object invoke = method1.invoke(student);
            System.out.println("-----調(diào)用靜態(tài)方法---->"+invoke.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
      

        System.out.println("調(diào)用靜態(tài)的方法");
        try {
            Class<?> cls2 = Class.forName("java.lang.String");
            Method method3=cls2.getMethod("valueOf", new Class[]{long.class});
            //靜態(tài)方法屬于類方法前计,所以調(diào)用的時候可以將invoke的第一參數(shù)為null,但是不能省略不寫。
//            Object object2=method3.invoke(null, 123);
            Object object2=method3.invoke(student垃杖,123);
            System.out.println(object2.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        /**
         * 打印結(jié)果:
         *-----調(diào)用靜態(tài)方法---->20
         * 調(diào)用靜態(tài)的方法
         * 123
         */

靜態(tài)方法屬于類方法男杈,所以調(diào)用的時候可以將invoke的第一參數(shù)為null,但是不能省略不寫。

七调俘、通過反射動態(tài)創(chuàng)建和訪問數(shù)組
Class<?>componentType=Class.forName("java.lang.String");
Object array=Array.newInstance(componentType, 10);
Array.set(array, 5, "通過反射動態(tài)創(chuàng)建和訪問數(shù)組 ");
System.out.println(Array.get(array, 5));

上述代碼中Array.newInstance(componentType, 10);表示創(chuàng)建一個componentType類型大小為10的數(shù)組伶棒。Array.set(array, 5, "通過反射動態(tài)創(chuàng)建和訪問數(shù)組 ");表示將數(shù)組第6個元素修改為”通過反射動態(tài)創(chuàng)建和訪問數(shù)組 “,Array.get(array, 5)表示訪問數(shù)組中第6個元素的值彩库。

七肤无、反射實踐完整代碼
package com.zcbl_videosurvey.test;

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

/**
 * Created by serenitynanian on 2018/2/23.
 */

public class Test {


    public static void main(String[] args) {
        //獲取類的Class對象
//        getClassInstances();
        /**
         * 獲取類的構(gòu)造方法
         * Constructor getConstructor(Class[] params) -- 獲取里面有特殊參數(shù)類型的公共構(gòu)造方法;
         * Constructor[] getConstructors() -- 獲取該類的所有公共的構(gòu)造方法骇钦;
         * Constructor getDeclaredConstructor(Class[] params) -- 獲取里面有特殊參數(shù)類型的構(gòu)造方法(不包含繼承的構(gòu)造方法)宛渐;
         * Constructor[] getDeclaredConstructor() -- 獲取該類的所有構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法);
         */
//        getClassConstructor1();
//        getClassConstructor2();
//        getClassConstructor3();
//        getClassConstructor4();
//        getClassDefaultConstructor();

        //通過反射獲取類的實例
//        getReflectClassInstances();

        //通過反射獲取字段
//        getFiled();
        //調(diào)用非靜態(tài)方法
//        invokeNoStaticMethod();
        //調(diào)用靜態(tài)方法
        invokeStaticMethod();
    }

    private static void invokeStaticMethod() {
        Student student = new Student();
        Class<? extends Student> aClass = student.getClass();
        try {
            Method method = aClass.getMethod("setAge", new Class[]{int.class});;
            method.invoke(student, 20);

            Method method1 = aClass.getMethod("getAge", new Class[]{});
            Object invoke = method1.invoke(null);
            System.out.println("-----調(diào)用靜態(tài)方法---->"+invoke.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


        System.out.println("調(diào)用靜態(tài)的方法");
        try {
            Class<?> cls2 = Class.forName("java.lang.String");
            Method method3=cls2.getMethod("valueOf", new Class[]{long.class});
            Object object2=method3.invoke(null, 123);
            System.out.println(object2.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        /**
         * 打印結(jié)果:
         *-----調(diào)用靜態(tài)方法---->20
         * 調(diào)用靜態(tài)的方法
         * 123
         */
    }


    private static void invokeNoStaticMethod() {
        Student student = new Student();
        Class aClass = student.getClass();
        try {
            Method method = aClass.getMethod("setName", new Class[]{String.class});
            method.invoke(student, "wanglu");
            Method method1 = aClass.getMethod("getName", new Class[]{});
            //第二個參數(shù)代表的參數(shù)數(shù)組值眯搭,如果沒有可以省略或者null或者new Object[0]
            Object invoke = method1.invoke(student);
            System.out.println("-------getName------>"+invoke.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * -------getName------>wanglu
         */
    }

    private static void getFiled() {
        Student student = new Student();
        Class<? extends Student> aClass = student.getClass();
//        System.out.println("獲取指定字段");
//        try {
//            Field field = aClass.getDeclaredField("height");
//            field.setAccessible(true);
//            field.set(student,20);
//            System.out.println("----student--->"+student.toString());
//        } catch (NoSuchFieldException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        /**
//         * 打印結(jié)果:
//         * ----student--->Student{name='null', height=20}
//         */

//        System.out.println("獲取該類及繼承的所有公有字段");
//        Field[]fields=aClass.getFields();
//        for (int i = 0; i < fields.length; i++) {
//            System.out.println("總共:"+fields.length+"當(dāng)前第"+(i+1)+"個 "+fields[i].toString());
//        }
//        /**
//         * 打印結(jié)果:
//         * 獲取該類及繼承的所有公有字段
//         * 總共:1當(dāng)前第1個 public java.lang.String com.zcbl_videosurvey.test.Person.sex
//         */

//        System.out.println("獲取該類的所有字段窥翩,不包含繼承的");
//        Field[]fields2=aClass.getDeclaredFields();
//        for (int i = 0; i < fields2.length; i++) {
//            System.out.println("總共:"+fields2.length+"當(dāng)前第"+(i+1)+"個 "+fields2[i].toString());
//        }
//        /**
//         * 打印結(jié)果:
//         *總共:3當(dāng)前第1個 private static int com.zcbl_videosurvey.test.Student.age
//         *總共:3當(dāng)前第2個 private java.lang.String com.zcbl_videosurvey.test.Student.name
//         *總共:3當(dāng)前第3個 private int com.zcbl_videosurvey.test.Student.height
//         */

        System.out.println("修改指定的靜態(tài)字段");
        try {
            Field field = aClass.getDeclaredField("age");
            field.setAccessible(true);
            field.set(null,180);
            System.out.println("-------->"+field.get(null));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 修改靜態(tài)字段
         *-------->180
         */

    }

    private static void getReflectClassInstances() {
        Class<String> aClass = String.class;
        System.out.println("通過指定構(gòu)造方法中參數(shù)類型,來獲取指定的構(gòu)造方法");
        Class[] paramterType = {char[].class, boolean.class};
        try {
            Constructor<String> declaredConstructor = aClass.getDeclaredConstructor(paramterType);
            System.out.println("declaredConstructor----->"+declaredConstructor.toString());
            //告訴虛擬機(jī)鳞仙,當(dāng)調(diào)用該構(gòu)造方法時寇蚊,不用進(jìn)行訪問權(quán)限的控制,也就是給反射開個綠燈;
            declaredConstructor.setAccessible(true);
            char[] chars = {'a',' ','s','t','u','d','e','n','t'};
            Object newInstance = declaredConstructor.newInstance(chars, false);
            System.out.println("-----object------->"+newInstance.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 通過指定構(gòu)造方法中參數(shù)類型棍好,來獲取指定的構(gòu)造方法
         *declaredConstructor----->java.lang.String(char[],boolean)
         *-----object------->a student
         */
    }

    private static void getClassDefaultConstructor() {
        Class<String> stringClass = String.class;
        System.out.println("5.獲取類默認(rèn)的構(gòu)造方法");
        try {
            Constructor<String> constructor = stringClass.getConstructor();
            System.out.println("5---->默認(rèn)的構(gòu)造方法:"+constructor.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 5.獲取類默認(rèn)的構(gòu)造方法
         *5---->默認(rèn)的構(gòu)造方法:public java.lang.String()
         */
    }

    private static void getClassConstructor4() {
        Class<String> stringClass = String.class;
        System.out.println("4.獲取所有的構(gòu)造方法仗岸,不包含繼承的");
        Constructor<?>[] declaredConstructors = stringClass.getDeclaredConstructors();
        for (int i = 0 ;i<declaredConstructors.length;i++) {
            System.out.println("總共:"+declaredConstructors.length+",當(dāng)前第"+(i+1)+"個"+declaredConstructors[i].toString());
        }
        /**
         * 打印結(jié)果如下:
         *4.獲取所有的構(gòu)造方法借笙,不包含繼承的
         總共:16扒怖,當(dāng)前第1個public java.lang.String(byte[],int,int)
         總共:16,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
         總共:16业稼,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
         總共:16盗痒,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
         總共:16,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
         總共:16盼忌,當(dāng)前第6個java.lang.String(char[],boolean)
         總共:16积糯,當(dāng)前第7個public java.lang.String(java.lang.StringBuilder)
         總共:16掂墓,當(dāng)前第8個public java.lang.String(java.lang.StringBuffer)
         總共:16,當(dāng)前第9個public java.lang.String(byte[])
         總共:16看成,當(dāng)前第10個public java.lang.String(int[],int,int)
         總共:16君编,當(dāng)前第11個public java.lang.String()
         總共:16,當(dāng)前第12個public java.lang.String(char[])
         總共:16川慌,當(dāng)前第13個public java.lang.String(java.lang.String)
         總共:16吃嘿,當(dāng)前第14個public java.lang.String(char[],int,int)
         總共:16,當(dāng)前第15個public java.lang.String(byte[],int)
         總共:16梦重,當(dāng)前第16個public java.lang.String(byte[],int,int,int)
         */
    }

    private static void getClassConstructor3() {
        String str = "";
        Class<? extends String> aClass = str.getClass();
        System.out.println("3.獲取所有的公共構(gòu)造方法:");
        Constructor<?>[] constructors = aClass.getConstructors();
        for (int i = 0 ;i<constructors.length;i++) {
            System.out.println("總共:"+constructors.length+"兑燥,當(dāng)前第"+(i+1)+"個"+constructors[i].toString());
        }
        /**
         * 打印結(jié)果如下:
         * 3.獲取所有的公共構(gòu)造方法:
         總共:15,當(dāng)前第1個public java.lang.String(byte[],int,int)
         總共:15琴拧,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
         總共:15降瞳,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
         總共:15,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
         總共:15蚓胸,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
         總共:15挣饥,當(dāng)前第6個public java.lang.String(java.lang.StringBuilder)
         總共:15,當(dāng)前第7個public java.lang.String(java.lang.StringBuffer)
         總共:15沛膳,當(dāng)前第8個public java.lang.String(byte[])
         總共:15扔枫,當(dāng)前第9個public java.lang.String(int[],int,int)
         總共:15,當(dāng)前第10個public java.lang.String()
         總共:15锹安,當(dāng)前第11個public java.lang.String(char[])
         總共:15短荐,當(dāng)前第12個public java.lang.String(java.lang.String)
         總共:15,當(dāng)前第13個public java.lang.String(char[],int,int)
         總共:15叹哭,當(dāng)前第14個public java.lang.String(byte[],int)
         總共:15忍宋,當(dāng)前第15個public java.lang.String(byte[],int,int,int)
         *
         */
    }

    private static void getClassConstructor2() {
        try {
            Class<?> aClass = Class.forName("java.lang.String");
            Class[] parameterTypes = {char[].class, boolean.class};
            System.out.println("2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法,該構(gòu)造方法不是繼承的");
            Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(parameterTypes);
            System.out.println("2---->declaredConstructor:"+declaredConstructor.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         *2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法话速,該構(gòu)造方法不是繼承的
         *2---->declaredConstructor:java.lang.String(char[],boolean)
         */
    }

    //獲取類的構(gòu)造方法
    private static void getClassConstructor1() {
        try {
            Class<?> aClass = Class.forName("java.lang.String");
            //1.獲取里面有特殊參數(shù)類型的公共構(gòu)造方法
            Class[] parameterTypes = {String.class};
            System.out.println("1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法");
            Constructor<?> constructor = aClass.getConstructor(parameterTypes);
            System.out.println("1---->constructor:"+constructor.toString());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        /**
         * 打印結(jié)果:
         * 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法
         * 1---->constructor:public java.lang.String(java.lang.String)
         */
    }

    //獲取類的Class對象
    private static void getClassInstances() {
        //1.方式一:通過將目標(biāo)類裝入到虛擬機(jī)的方式獲取該類的Class對象;
        //此方式通常會用在:無法直接引用目標(biāo)類的情況讶踪;
        try {
            Class<?> aClass = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //方式二:通過類或類的對象獲取類的Class對象
        Class<String> stringClass1 = String.class;
        //或者下面的方式
        String str = "";
        Class<? extends String> stringClass2 = str.getClass();

    }


}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市泊交,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柱查,老刑警劉巖廓俭,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唉工,居然都是意外死亡研乒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門淋硝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雹熬,“玉大人宽菜,你說我怎么就攤上這事「捅ǎ” “怎么了铅乡?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烈菌。 經(jīng)常有香客問我阵幸,道長,這世上最難降的妖魔是什么芽世? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任挚赊,我火速辦了婚禮,結(jié)果婚禮上济瓢,老公的妹妹穿的比我還像新娘荠割。我一直安慰自己,他們只是感情好旺矾,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布涨共。 她就那樣靜靜地躺著,像睡著了一般宠漩。 火紅的嫁衣襯著肌膚如雪举反。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天扒吁,我揣著相機(jī)與錄音火鼻,去河邊找鬼。 笑死雕崩,一個胖子當(dāng)著我的面吹牛魁索,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盼铁,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼粗蔚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饶火?” 一聲冷哼從身側(cè)響起鹏控,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肤寝,沒想到半個月后当辐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡鲤看,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年缘揪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡找筝,死狀恐怖蹈垢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袖裕,我是刑警寧澤曹抬,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站陆赋,受9級特大地震影響沐祷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秸歧。 院中可真熱鬧,春花似錦兢榨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至兼雄,卻和暖如春吟逝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赦肋。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工块攒, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佃乘。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓囱井,卻偏偏與公主長得像,于是被迫代替她去往敵國和親趣避。 傳聞我的和親對象是個殘疾皇子庞呕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內(nèi)容