1. 程式人生 > 資訊 >加拿大皇家銀行:蘋果或購買比特幣,該公司應建立加密交易所

加拿大皇家銀行:蘋果或購買比特幣,該公司應建立加密交易所

技術標籤:Java基礎

學習目標


掌握通過反射獲得類名
掌握通過反射例項化其他類的物件
掌握通過反射獲得其他類中的全部建構函式
掌握獲得其他類中的全部屬性
掌握呼叫其他類中的方法
掌握通過反射操作屬性
掌握通過反射取得陣列的資訊

Java 語言的反射機制

  1. 在Java執行時環境中,對於任意一個類物件,能否知道這個類有哪些屬性和方法?對於任意一個物件,能否呼叫它的任意一個方法?答案是肯定的。這種動態獲取類的資訊以及動態呼叫物件的方法的功能來自於Java 語言的反射(Reflection)機制。
  2. Java 反射機制主要提供了以下功能
    在執行時判斷任意一個物件所屬的類。
    在執行時構造任意一個類的物件。
    在執行時判斷任意一個類所具有的成員變數和方法。
    在執行時呼叫任意一個物件的方法
    在這裡插入圖片描述
  3. Reflection 是Java被視為動態(或準動態)語言的一個關鍵性質。這個機制允許程式在執行時透過Reflection APIs取得任何一個已知名稱的class的內部資訊,包括其modifiers(諸如public, static 等許可權)、superclass(例如Object)、實現interfaces(例如Serializable),也包括fields(屬性)和methods(方法)的所有資訊,並可於執行時改變fields內容或呼叫methods
  4. 一般而言,開發者社群說到動態語言,大致認同的一個定義是:“程式執行時,允許改變程式結構或變數型別,這種語言稱為動態語言”。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言
  5. 儘管在這樣的定義與分類下Java不是動態語言,它卻有著一個非常突出的動態相關機制:Reflection。這個字的意思是“反射、映象、倒影”,用在Java身上指的是我們可以於執行時載入、探知、使用編譯期間完全未知的classes。換句話說,Java程式可以載入一個執行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其物件實體、或對其fields設值、或喚起其methods。這種“看透class”的能力(the ability of the program to examine itself)被稱為introspection(內省、內觀、反省)。Reflection和introspection是常被並提的兩個術語

Java Reflection API 簡介

  • 在JDK中,主要由以下類來實現Java反射機制,這些類(除了Class類在java.lang包),其他類都位於java.lang.reflect包中
    Class類:代表一個類。
    Field 類:代表類的成員變數(成員變數也稱為類的屬性)。
    Method類:代表類的方法。
    Constructor 類:代表類的構造方法。
    Array類:提供了動態建立陣列,以及訪問陣列的元素的靜態方法
  • 在java.lang.Object 類中定義了getClass()方法,因此對於任意一個Java物件,都可以通過此方法獲得物件的型別。Class類是Reflection API 中的核心類,它有以下方法
    getName():獲得類的完整名字。
    getFields():獲得類的public型別的屬性。
    getDeclaredFields():獲得類的所有屬性。
    getMethods():獲得類的public型別的方法。
    getDeclaredMethods():獲得類的所有方法。
  • getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name引數指定方法的名字,parameterTypes 引數指定方法的引數型別。
  • getConstructors():獲得類的public型別的構造方法。
  • getConstructor(Class[] parameterTypes):獲得類的特定構造方法,parameterTypes 引數指定構造方法的引數型別。
  • newInstance():通過類的不帶引數的構造方法建立這個類的一個物件。
  • (2)通過預設構造方法建立一個新物件
    Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
    以上程式碼先呼叫Class類的getConstructor()方法獲得一個Constructor 物件,它代表預設的構造方法,然後呼叫Constructor物件的newInstance()方法構造一個例項。
  • (3)獲得物件的所有屬性:
    Field fields[]=classType.getDeclaredFields();
    Class 類的getDeclaredFields()方法返回類的所有屬性,包括public、protected、預設和private訪問級別的屬性

例項方法

public static void main(String[] args) {
        try {

            //第一種方法
            //根據類名.class屬性獲取該類的位元組碼類物件,該類物件是在虛擬機器載入類時建立
            Class<Student> s1 = Student.class;
            Class<Student> s2 = Student.class;

            //第二種方法
            //呼叫class的靜態方法,通過類的完整名稱字串forName,獲取Class例項。?是不知道那個類
            Class<?> s3 = Class.forName("com.entor.test.demo46_反射.test.Student");

            //第三種方法
            Student s = new Student();
            Class<? extends Student> s4 = s.getClass();

            //獲取該類中所有的公共屬性
            System.out.println("--------------------所有公共屬性------------------");
            Field[] fields = s1.getFields();
            for (Field field : fields) {
                System.out.println(field.getName());
            }

            //獲取類中的所有屬性
            System.out.println("--------------------所有屬性------------------");
            Field[] fields1 = s1.getDeclaredFields();
            Arrays.stream(fields1).forEach(ss -> {
                System.out.print("屬性修飾詞  "+ Modifier.toString(ss.getModifiers()));
                System.out.print("屬性型別  "+ss.getType().getSimpleName());
                System.out.print("屬性名稱  "+ss.getName());
                System.out.println("\n");
            });

            //獲取類中所有的公共方法
            System.out.println("--------------------所有公共方法------------------");
            Method[] methods = s1.getMethods();
            Arrays.stream(methods).forEach(ss -> {
                System.out.print("屬性修飾詞  "+ Modifier.toString(ss.getModifiers()));
                System.out.print("屬性型別  "+ss.getReturnType().getSimpleName());
                System.out.print("屬性名稱  "+ss.getName());
                Class<?>[] parameterTypes = ss.getParameterTypes();
                System.out.print("--------------引數列表--------------");
                Arrays.stream(parameterTypes).forEach(sss->{
                    System.out.print("屬性名稱  "+sss.getSimpleName());
                });
                System.out.println("\n");
            });

            //獲取類中所有的方法
            System.out.println("--------------------所有方法------------------");
            Method[] methods1 = s1.getDeclaredMethods();
            Arrays.stream(methods1).forEach(ss -> {
                System.out.print("屬性修飾詞  "+ Modifier.toString(ss.getModifiers()));
                System.out.print("屬性型別  "+ss.getReturnType().getSimpleName());
                System.out.print("屬性名稱  "+ss.getName());
                System.out.println("\n");
            });


            System.out.println(s1 == s2);//true 單例模式
            System.out.println(s1 == s3);//true 單例模式
            System.out.println(s1 == s4);//true 單例模式
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }