Java反射総括(一)


今日はjavaの中で非常に重要な反射をまとめて、ここでは反射の概念を見せないで、他の技術と同じように、私は1つの需要から始めて、みんなを連れて一歩一歩して、みんなに何が反射なのかとなぜ反射メカニズムを使うのかを理解させます.
一、需要説明
仮に私は今1种のゲームを开発して、ゲームの名称は《无敌破壊神》と言って、プレーヤーは5中の英雄の役を选ぶことができて、それぞれ:1.神を破壊する法師3.戦神アテナの女神精霊という5人の英雄の役はすべて私がでたらめを考えているので、具体的には私たちが関心を持っているのではないでしょうか.この5人の英雄はすべて自分の技能を持っていて、例えば走って、避けて、普通の技能と大技など、プレイヤーはその中の1人の英雄を選んで、この英雄の技能は確定しました.これは需要の簡単な説明で、私たちはこれだけの情報だけで十分です.
二、需要分析
まずこのゲームを分析してみましょう.まず、5人の英雄がいます.コードに対応するのは5つのクラスです.それから、5人の英雄はそれぞれのスキルといくつかの属性を持っています.これらのコードに対応するのはクラスの属性と方法です.javaで簡単にこの5人の英雄のスキル呼び出しをシミュレートします.次に、どのように実現するかを具体的に見てみましょう.
ここでは多くのバージョンを書きます.各バージョンは前のバージョンよりコードを改善します.機能は変わりません.改善の考え方と原因を理解するのに便利です.
バージョン1
バージョン1は最も馬鹿な書き方で、ここでは一部のコードを示します.
public class Test1 {
    public static void main(String[] args) {
        Hero_PoHuaiShen hero1 = new Hero_PoHuaiShen("     ");
        hero1.run();
    }
}

class Hero_PoHuaiShen {
    String name;
    Hero_PoHuaiShen(String name) {
        this.name = name;
    }
    public void run() {
        System.out.println(name+" ");
    }
}

まず説明しますが、ここでは他の4人の英雄のクラスの作成を省略し、1つしか書いていません.そして、この英雄の属性と方法は最も簡単ですが、これらは問題を説明するのに十分です.ここでのヒーローは具体的なクラス,ヒーローの属性とスキル対応クラスの属性と方法に対応し,シミュレーションヒーロースキルはこのクラスをインスタンス化し,オブジェクトを介してヒーローを呼び出す方法である.
今、この書き方を分析してみると、この書き方は英雄ごとにクラスを書いています.英雄の種類が増えたら、英雄クラスを書き直して、その方法を実現しなければなりません.そして、英雄ごとに同じ属性と同じ技能を保証することはできません.ここで同じことは属性の個数と種類を指しているので、このように書くのはよくありません.バージョン2がどのように書かれているか見てみましょう
バージョン2
上のコードについて分析してみましょう.ヒーローにはrun()メソッドがあります.このメソッドをインタフェースに書くことができますか.コードは次の通りです.
interface Hero{
    public void run();
    public void kill();
}

class     implements Hero {
    @Override
    public void run() {
        System.out.println("     ");
    }

    @Override
    public void kill() {
        System.out.println("      ");
    }
}

ここではヒーローのスキルを提案していますが、ヒーローごとにHeroという言い訳をしてキャラクターの書き換え方法に従えばいいので、ヒーローのスキルの種類を統一することができます.属性の種類と個数を統一するには、もう一つのクラスを書くことができます.中にはヒーローのプロパティだけを書いて、具体的なヒーロークラスでこのクラスを継承すればいいです.次に、メイン関数でこのクラスを呼び出すといいです.
public class Test1 {
    public static void main(String[] args) {
            p = new    ();
        p.run();
        p.kill();
    }
}

このバージョンはバージョンより少し良いですが、ゲームの役割はユーザーが選択したもので、どのようにユーザーの選択に基づいて具体的なクラスを生成しますか?バージョン3を見てください.
バージョン3
ユーザの選択に文字列が存在すると仮定し、この文字列に基づいて対応するクラスを生成します.
public static void main(String[] args) {
        String choice = "   ";
        Hero h=null;
        if(choice.equals("   ")){
            h = new    ();
        }
        if(choice.equals("  ")){
            h = new   ();
        }
        if(choice.equals("  ")){
            h = new   ();
        }
        if(choice.equals("     ")){
            h = new      ();
        }
        if(choice.equals("  ")){
            h = new   ();
        }
    }

if判定文またはswitch分岐文でプレイヤーの選択に応じて具体的なヒーロークラスを作成できるという書き方はユーザ選択の柔軟性を高めているが、ヒーローの種類が多い場合や新しいヒーローが追加されている場合、判定文を追加するのは面倒で、バージョン3のコードを改善し続けることができるのだろうか.はい、ここで反射が出ますから、見てみましょう.
バージョン4
ここで変更したコードはメイン関数呼び出し部分であり、長い判断ユーザーが選択したコードについては、いくつかの簡単なコードで置き換えることができ、機能は完全に同じです.
public class Test1 {
    public static void main(String[] args) {
        String choice = "   ";
        try{
            Class c= Class.forName("com.one."+choice);
            Hero h = (Hero)c.newInstance();
            h.run();
            h.kill();
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

このように書くと、ヒーロー名を変更したり、多くのヒーローキャラクターを追加したりしても、このコードを変更する必要はありません.強いのではないでしょうか.コードを見てみましょう.
Class c= Class.forName("com.one."+choice);

この行のコードは肝心です.ここでClassというクラスについてお話しします.javaはオブジェクト向けのプログラミング言語であることはよく知られています.各クラスには多くのオブジェクトがありますが、javaの中のクラスもオブジェクトですが、どのクラスのオブジェクトですか.このクラスはクラスです.すべてのクラスがクラスの対象です.まずこのように理解してください.この行コードの機能はクラス名でクラスを取得することであり,ここでは文字列でクラスを取得するため,我々が取得するクラスが存在しない場合がある可能性があるため,ここでは異常をキャプチャする必要がある.このクラスを取得した後、クラスのオブジェクトcを介してオブジェクトタイプであるインスタンスオブジェクトを生成するので、タイプ変換が必要であり、hによって特定のヒーローのメソッドを呼び出すことができる.このように書くメリットは明らかで、まずコード量が減少しましたが、これは主なメリットではありません.別の例を見て反射のメリットを見てみましょう.
開発ではデータベースがよく使われますが、mysqlをリンクするコードは以下の通りです.
public static Connection getConnection() {
        Connection conn=null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/"
                    + "schema1","root","123456");
        }catch(Exception e){
            e.printStackTrace();
        }
        return conn;
}

ここでデータベースドライバをロードするのは反射で、コードがコンパイルされてから実行されることはよく知られていますが、コンパイルされたコードはこれ以上変更できません.今、他のデータベースを使用するには、他のデータベースドライバをロードする必要があります.ユーザー名、パスワード、urlなどが変更される可能性がありますが、これらはコードに書かれてコンパイルされています.ソースコードを変更してコンパイルしない限り、これ以上変更することは不可能です.開発では多くのプロファイルが使用されます.データベースドライバ、ユーザー名、パスワード、urlを1つのプロファイルに書いて、このプロファイルの情報をコードに読み込めばいいです.これにより、データベースを交換したり、パスワードを変更したりすると、ソースコードを変更したり、再コンパイルする必要がなくなります.
これは、ユーザの選択に基づいてクラスを動的にロードし、実行する方法であり、コードの柔軟性が大きく、コードが実行されると、その属性と方法を含むクラスのすべての情報を取得し、このクラスの方法を実行することができる.実はjavaweb開発で使われている様々なフレームワークの実現は反射に基づいて実現されています.この方面で開発した友达は、これらのフレームワークに多くのプロファイルが記入されていることを知っています.これは、ユーザーの選択に基づいて動的にいくつかのクラスをロードし、原理は反射です.
この考え方が反射とは何か、具体的にどのように使うかを理解してくれることを願っています.私の別のブログを見てください.リンク:Java反射総括(二)