初認識java反射

14600 ワード

  • タイプ情報
  • 1.Classオブジェクト
  • Classオブジェクトを取得する3つの方法
  • 1.2類字面定数
  • 1.3汎化Class参照
  • 2.タイプ変換前にチェック
  • 三.反射はんしゃ:実行時のクラス情報じっこうじのクラスじょうほう
  • 3.1反射とは何か、RTTIとの違い
  • getDeclaredFields()とgetFields()メソッドの違い



  • タイプ情報
    一.Classオブジェクト
    Classオブジェクトは、すべてのクラスのすべての「一般」オブジェクトを作成するために使用されます.JAvaはクラスオブジェクトを使用してRTTI(実行時にクラスとオブジェクトを識別する情報)を実行します.このような操作を実行していても.
    クラスはプログラムの一部で、各クラスにはClassオブジェクトがあります.言い換えれば、新しいクラスが作成されるたびにClassオブジェクトが生成されます.このクラスのオブジェクトを生成するために、このプログラムを実行するjava仮想マシン(JVM)は、「クラスローダ」のサブシステムを使用します.
    クラスローダサブシステムは、実際にはクラスローダチェーンを含むことができるが、JVM実装の一部であるオリジナルクラスローダは1つしかない.オリジナルクラスローダは、java APIクラスを含むいわゆる信頼性クラスをロードし、通常はローカルエリアからロードされる.このチェーンでは、通常、追加のクラス・ローダを追加する必要はありませんが、Webサーバ・アプリケーションをサポートするためにクラスを特定の方法でロードしたり、ネットワークでクラスをダウンロードしたりするなど、特別なニーズがある場合は、追加のクラス・ローダを接続する方法があります.
    すべてのクラスは、最初に使用したときにJVMに動的にロードされ、プログラムがクラスの静的メンバーへの参照を作成するとロードされます.この証明コンストラクタもクラスの静的メソッドであり、コンストラクタの前にstaticキーワードが使用されていない場合でも、newオペレータを使用してクラスを作成する新しいオブジェクトは、クラスの静的メンバーへの参照として扱われます.
    したがってjavaプログラムは、実行を開始する前に完全にロードされるのではなく、必要に応じてロードされます.
    クラスローダはまず、クラスのClassオブジェクトがロードされているかどうかを確認します.まだロードされていない場合、デフォルトのクラスローダはクラス名に基づいて検索されます.classファイル(たとえば、追加のクラス・ローダがデータベースでバイトコードを検索する場合があります).このクラスのバイトコードがロードされると、破壊されていないことを確認するために検証を受けます.javaコードが含まれていません.
    クラスのクラスオブジェクトがメモリにロードされると、そのクラスのすべてのオブジェクトを作成するために使用されます.
             Class.forName(「クラス名」)は、指定されたクラス名に基づいて、そのようなオブジェクトを操作するための参照を取得できます.このメソッドで書かれたクラス名が見つからない場合、彼は例外ClassNotFoundExceptionを投げ出します.いつでも、実行時にタイプ情報を使用するには、まず適切なClassオブジェクトへの参照を取得する必要があります.Class.forName(「クラス名」)は、Classリファレンスを取得するためにこのタイプのオブジェクトを持つ必要がないため、この機能を実現する便利な方法です.ただし、オブジェクトが既に存在する場合(たとえば、オブジェクトがnewされている場合)、このオブジェクトはgetClassメソッドを呼び出してClass参照を取得できます.このメソッドはルートクラスObjectの一部に属し、オブジェクトの実際のタイプを表すClass参照を返します.
    Classオブジェクトを使用すると、実行時にオブジェクトの完全なクラス継承構造を見つけることができます.
    Classオブジェクトを取得する3つの方法
  • ランタイムクラス自体のclass属性(インスタンス化オブジェクトは不要):たとえばClass s=String,class
  • .
  • Classを呼び出す.forName()メソッド(オブジェクトをインスタンス化する必要はありません):classオブジェクトを取得するために必要なフルパス名を入力するだけです.たとえば、Class
  • 1.2類字面定数
    JAvaはまた、クラスの字面が常に明るい、文法が次のクラス名のようになっているClassオブジェクトへの参照を生成する別の方法を提供する.class
    クラスの字面定数は、通常のクラスだけでなく、インタフェース、配列、および基本データ型にも適用できます.
    「.class」を使用してClassオブジェクトへの参照を作成する場合、そのClassオブジェクトは自動的に初期化されません.クラスを使用するための準備には、次の3つのステップがあります.
  • にロードされます.これはクラス・ローダによって実行され、通常はclasspathで指定されたパスでバイトコードを検索しますが、これは必須ではありません.これらのバイトコードからClassオブジェクトを作成します.
  • リンク.リンクフェーズでは、クラス内のバイトコードを検証し、静的ドメインにストレージスペースを割り当て、必要に応じて、このクラスが作成した他のクラスへのすべての参照を解析します.
  • 初期化.クラスにスーパークラスがある場合は、クラスを初期化し、静的初期化器と静的初期化ブロックを実行します.

  • 1.3汎化Class参照
    Classリファレンスは常にクラスのインスタンスを作成することができるClassオブジェクトを指し、これらのインスタンスを機能するすべてのメソッドコードを含む.クラスの静的メンバーも含まれているため、Class参照は、クラスのオブジェクトの正確なタイプを表し、そのオブジェクトはClassクラスのオブジェクトです.
    Java SE 5の設計者は、クラス参照が指すクラスオブジェクトのタイプを限定することを許可することによって、そのタイプをより具体的にする機会を見定め、ここでは、クラスのように汎用化して所望のクラス参照を限定することができる汎用構文を用いる.
    注意:Classを使用する場合.新Instance()インスタンスオブジェクトを取得する場合は、デフォルトのコンストラクタが必要です.そうしないと、例外が報告されます.
    汎用構文をClassオブジェクトに使用する場合:newInstance()はオブジェクトの正確な情報を返します.Objectだけではありませんが、このオブジェクトのスーパークラスClassオブジェクトが手元にある場合は、このスーパークラスClassのnewInstance()メソッドを呼び出すと、Objectオブジェクトのみで受信できます.
    二.タイプ変換前にチェック
    現在知られているランタイム識別クラスのタイプ情報は、次の3つです.
  • 従来のタイプ変換、例えばA a=(A)b.しかし、誤ったタイプ変換が実行するとClassCastException異常が放出される.
  • はオブジェクトのタイプClassオブジェクトを表し、Classオブジェクトを問い合わせることで実行時に必要な情報を取得することができる.
  • キーワードinstanceof.オブジェクトが特定のタイプのインスタンスであるかどうかを示すブール値を返します.

  • 三.反射はんしゃ:実行時のクラス情報じっこうじのクラスじょうほう
    3.1反射とは何か、RTTIとの違い
    主にプログラムが自身の状態や行為にアクセス、検出、修正できる能力を指す.重要なのは、反射に不思議なところはないことを認識し、反射を通じて未知のタイプのオブジェクトと付き合うとき、JVMの知識はこのオブジェクトがどの特定のクラスに属しているか(RTTIのように)を簡単に検査することである.他のことをする前にどのクラスのClassオブジェクトをロードする必要がありますか?だから、どのクラスのですか.classファイルは、JVMにとって取得可能である必要がある:すなわち、ローカルマシン上であるか、ネットワークを介して取得可能であるため、RTTIと反射との間の真の違いは、RTTIにとってコンパイラがコンパイル時に開き、チェックする.classファイル(言い換えれば、オブジェクトを通常の方法で呼び出すことができるすべての方法).しかし反射にとっては.classファイルはコンパイル時に取得できません.したがって、実行時に開く、チェックする.classファイル
    Classクラスとjava.lang.reflectクラスライブラリは、Field,MethodおよびConstructorクラス(クラスごとにMemberインタフェースを実現する)を含む反射の概念をサポートする.これらのタイプのオブジェクトは、未知クラスに対応するメンバー情報を表すJVMによって実行時に作成する.これにより、Constructorで新しいオブジェクトを作成し、どのget()とset()メソッドでFieldオブジェクトに関連付けられたフィールドを読み取り、修正し、invoke()メソッドでMethodオブジェクトに関連付けられたメソッドを呼び出し、また、getFields()、getMethods()とgetConstructors()などの便利なメソッドを呼び出して、フィールド、メソッド、コンストラクタを表すオブジェクトの配列を返すことができます.
    getDeclaredFields()とgetFields()メソッドの違い
    クラスに属性がある場合、両方のメソッドは1つのField配列を返す.ここでgetDeclaredFields()メソッドはpublic,protected,default,privateを含むすべてのパラメータを返す.getFields()はpublicのパラメータのみを返す.getMethods()もgetConstructors()も同じです
    次のdomainクラスがあり、彼のすべての属性情報、メソッド情報、コンストラクタの情報を実行時に読み出すことができます.
    /**
     * @description  TBapInterParadomain
     * @author [email protected]
     * @date   20180301 15:47:23
     * @review [email protected]/2018-03-01
     */
    public class TBapInterPara{
        /**
         * UUID
         */
            private String uuid;
    
        /**
         *     
         */
            private String fieldNm;
    
        /**
         *     
         */
            private String fieldTyp;
    
        /**
         *       
         */
            private String required;
    
        /**
         *   
         */
            private String remarks;
    
        /**
         *   
         */
            private String levelPara;
    
        /**
         *    UUID
         */
            private String infoUuid;
    
            private ParameVo parameVo;
    
            private List parameVos;
    
    
        public TBapInterPara() {
            super();
        }
    
        /**
         * get UUID
         */
            public String getUuid() {
                return uuid;
            }
    
        /**
         * set UUID
         */
            public void setUuid(String uuid) {
                this.uuid = uuid;
            }
    
        /**
         * get     
         */
            public String getFieldNm() {
                return fieldNm;
            }
    
        /**
         * set     
         */
            public void setFieldNm(String fieldNm) {
                this.fieldNm = fieldNm;
            }
    
        /**
         * get     
         */
            public String getFieldTyp() {
                return fieldTyp;
            }
    
        /**
         * set     
         */
            public void setFieldTyp(String fieldTyp) {
                this.fieldTyp = fieldTyp;
            }
    
        /**
         * get       
         */
            public String getRequired() {
                return required;
            }
    
        /**
         * set       
         */
            public void setRequired(String required) {
                this.required = required;
            }
    
        /**
         * get   
         */
            public String getRemarks() {
                return remarks;
            }
    
        /**
         * set   
         */
            public void setRemarks(String remarks) {
                this.remarks = remarks;
            }
    
        /**
         * get   
         */
            public String getLevelPara() {
                return levelPara;
            }
    
        /**
         * set   
         */
            public void setLevelPara(String levelPara) {
                this.levelPara = levelPara;
            }
    
        /**
         * get    UUID
         */
            public String getInfoUuid() {
                return infoUuid;
            }
    
        /**
         * set    UUID
         */
            public void setInfoUuid(String infoUuid) {
                this.infoUuid = infoUuid;
            }
    
    }
    
    
    /**
     * @program: demo
     * @description:   
     * @author: [email protected]
     * @create: 2018-03-29 16:02
     **/
    public class Demo11 {
        public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
            Class tBapInterParaClass=TBapInterPara.class;
            Field[] fields = tBapInterParaClass.getDeclaredFields();//       ,  private 
            Method[] methods = tBapInterParaClass.getMethods();
            tBapInterParaClass.getDeclaredMethods();
            Constructor>[] constructors = tBapInterParaClass.getConstructors();
            for (int i = 0; i < fields.length; i++) {
                System.out.println(fields[i].getType());
                System.out.println(fields[i].getName());
                System.out.println("-----------------");
    
            }
            System.out.println("methods:");
            for (int k = 0; k < methods.length; k++) {
                System.out.println(methods[k].getName());
                System.out.println("-----------------");
            }
            System.out.println("constructors:");
            for (int j = 0; j < constructors.length; j++) {
                System.out.println(constructors[j]);
            }
        }
    }
    

    実行結果
    class java.lang.String
    uuid
    -----------------
    class java.lang.String
    fieldNm
    -----------------
    class java.lang.String
    fieldTyp
    -----------------
    class java.lang.String
    required
    -----------------
    class java.lang.String
    remarks
    -----------------
    class java.lang.String
    levelPara
    -----------------
    class java.lang.String
    infoUuid
    -----------------
    class tese2.ParameVo
    parameVo
    -----------------
    interface java.util.List
    parameVos
    -----------------
    methods:
    getUuid
    -----------------
    setUuid
    -----------------
    getFieldNm
    -----------------
    setFieldNm
    -----------------
    getFieldTyp
    -----------------
    setFieldTyp
    -----------------
    getRequired
    -----------------
    setRequired
    -----------------
    getRemarks
    -----------------
    setRemarks
    -----------------
    getLevelPara
    -----------------
    setLevelPara
    -----------------
    getInfoUuid
    -----------------
    setInfoUuid
    -----------------
    wait
    -----------------
    wait
    -----------------
    wait
    -----------------
    equals
    -----------------
    toString
    -----------------
    hashCode
    -----------------
    getClass
    -----------------
    notify
    -----------------
    notifyAll
    -----------------
    constructors:
    public tese2.TBapInterPara()