近くに8000の呉服を反映した言葉| []高度なJavaの、Javaのリフレクション簡潔

Javaの反射機構簡潔

コンテンツ
概念反射機構の
基本クラス2クラスは、反射
反射の3.
応用例4の反射します

著者について:フルスタックの研究ノート、人々がで作業している
マイクロチャネル公共番号:第公開日より素敵な一日のプッシュエッセイ
ここに画像を挿入説明

反射の概念:

動作状態では、任意のクラスのために、どの動的に取得し、(独自のメソッドとプロパティを含む)、そのメソッドとプロパティを呼び出すことができる任意のオブジェクトのすべてのプロパティと、この種の方法を、得ることができます機能情報と動的呼び出し対象の方法は、反射Java言語と呼ばれています。反射は動的言語への鍵と見られています。反射は、単に対応するJavaクラスのJavaの様々な構成要素にマッピングされます。

人気話すには、反射によって、クラスには、何もすることができ取得したい、私たちに対して完全に透過的です。この方法は、方法を、構築プロパティ含みます。

Javaのリフレクションメカニズムが機能を提供します

いずれかのオブジェクトのランタイム・クラスに属し分析するステップと、
実行時にオブジェクトのコンストラクタ任意のクラス、
メンバ変数とメソッドの任意のクラスを分析することは、実行時に有しており、
実行時に指定されたオブジェクトのメソッドを呼び出し、
動的プロキシを生成します。

実際には、これはまた、動的および静的言語に関連して、我々は反射呼んで、Java言語自体は動的言語ではありませんが、彼は非常に著名なダイナミックな機構を備えています。
動的言語は何ですか?つまり、プログラムは、(ないコンパイル時、実行するための時間であることに注意してください)を実行しているときは、プログラム構造や変数の型を変更することができます。逆に、静的には、そのような人格ではありません。

クラスは、基本クラスを反映しました

Classクラスは、私は反射に勉強したいので、あなたが最初のクラス、クラスの基本的な概念を習得する必要があり、達成するための反射の基礎です。
何クラスですか?ClassクラスはClassクラスは、すべてのクラスのクラスであるように、オブジェクトクラスのインスタンスです。

クラスの解剖学的構造に、あなたは最初のバイトコードファイルオブジェクトクラスを取得する必要があります。クラスは、各タイプのクラスファイルバイトコード対応のオブジェクトを取得するために解剖学クラス、最初によって使用される方法です。

クラスなしのパブリックコンストラクタクラスは、クラスオブジェクトクラスは時間Java仮想マシンとクラスローダによって構成された自動呼び出しメソッドdefineClassによってロードされ、それが明示的にクラスのオブジェクトを宣言されていません。ここではまたのようなもの、の負荷を必要とします

簡単に言うとは説明します。

クラスローダ:クラスは、システムは接続をロードすることで、この初期化初期化クラス3つの段階にメモリにロードされていない場合、プログラムはクラスにする必要があります時間

負荷:クラスファイルを参照するには、クラスのオブジェクトを作成するために誰を(ファイルはコンパイルがの.classファイルになった後)、メモリに読み込まれ、
任意のクラスを使用する場合、Classオブジェクトを構築するシステムは、最初の時間は、第二になります時間はクラスが存在するかを決定します。

接続:あなたは正しい内部構造を持っていることを確認し、かつ協調や、他の種類の
クラスの静的メンバのメモリを割り当てる準備ができて、そしてデフォルトの初期値を設定
し、解像度を作る:バイナリデータクラスの文字参照は、直接参照に置き換えられました。

Classオブジェクトの上にいえば直接作成することはできませんが、我々は他の方法でClassクラスを取得することができ、あなたは通常、クラスの後にクラスを取得するためにリフレクションを使用することができます私たちが望むクラスのクラスを取得するための3つの方法が、あります。

クラス(クラスのバイトコードオブジェクトの取得)を取得する3つの方法:

最初:オブジェクトへのアクセスを使用して、使用は、getのgetClassオブジェクト

Person person = new Person();
Class clazz = person.getClass();

第二:静的クラスプロパティを使用

Class clazz = Person.class

第三:静的メソッドにforName Classクラス(クラス名の文字列)
注;クラスのパッケージ名のフルネームを書きます

Class clazz = Calss.forName("…….");

それの楽しみを再生する方法を反映さて、ここでの焦点、!

使用方法は、反射##

それがtrueの場合を見てみましょう、反射のクラスのいずれかを介して取得することができるものを言います。

やっへの第一歩もちろん、これはクラスの前の3つのメソッドを喜ばクラスによって得ることができます。三つの方法がありますが、私たちはまずそれの例でなければなりません!
コード

//获取Class第一种方法
Student student = new Student();
Class clazz = student.getClass();
//获取Class第二种方法
Class clazzTwo = Student.class;
//获取Class第三种方法
Class clazzThree = Class.forName("demo.qzxxbj.entity.Student");

System.out.println("第一个"+clazz+"\n第二个"+clazzTwo+"\n第三个"+clazzThree);

結果

第一个class demo.qzxxbj.entity.Student
第二个class demo.qzxxbj.entity.Student
第三个class demo.qzxxbj.entity.Student

Classオブジェクトは、あなたは、三つの方法が同じであるに違いを見ることはできません。
第三の方法は、クラスが見つからない例外がスローされますです。
学生は、単純なクラスは、任意のクラス可能です。

クラスのいずれかのクラスでプロパティを取得します。
コードの学生クラス

package demo.qzxxbj.entity;

/**
 * @author 微信公众号:全栈学习笔记
 * @date 2020/3/29
 * @description
 */

public class Student {
private String name;
private Integer age;
private String sex;
public int number;

public int getNumber() {
    return number;
}

public void setNumber(int number) {
    this.number = number;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Integer getAge() {
    return age;
}

public void setAge(Integer age) {
    this.age = age;
}

public String getSex() {
    return sex;
}

public void setSex(String sex) {
    this.sex = sex;
}

}

以下の方法は、クラスAの第二を得るために使用される、より簡潔

	//获取Class第二种方法
    Class clazzTwo = Student.class;

    //获取该类指定属性名的public成员变量,包括父类的
    Field field = clazzTwo.getField("number");

    //field   public int demo.qzxxbj.entity.Student.number
    System.out.println("该类指定属性名的public成员变量,包括父类的"+field);

    //获取该类指定名称声明的变量,即不包括父类的
    Field deField = clazzTwo.getDeclaredField("name");

    // deField  private java.lang.String demo.qzxxbj.entity.Student.name
    System.out.println("该类所有声明的变量,即不包括父类的"+deField);

    //获取该类所有的public声明的成员变量
    Field fields[] = clazzTwo.getFields();

    System.out.println("public声明的变量:");
    //public int demo.qzxxbj.entity.Student.number
    for (Field field1:fields){
        System.out.println(field1);
    }

    //获取该对象的所有成员变量
    Field deFields[] = clazzTwo.getDeclaredFields();
    System.out.println("该对象的所有成员变量");
    //private java.lang.String demo.qzxxbj.entity.Student.name
    //private java.lang.Integer demo.qzxxbj.entity.Student.age
    //private java.lang.String demo.qzxxbj.entity.Student.sex
    //public int demo.qzxxbj.entity.Student.number
    for (Field field1:deFields){
        System.out.println(field1);
    }

れるGetFields()、のgetField(文字列名)、getDeclaredFields()、差異getDeclaredField(文字列名を)忘れないでください、あなたはポイントを把握するために、この知識を取ることができるようになります!

クラスメソッドのいずれかのメンバーによる買収

またはコードを参照してください!

メンバメソッド取得方法

	//获取Class第二种方法
    Class clazzTwo = Student.class;
    //根据方法名以及参数类型获取,只能获取public声明的方法,包括父类的
    Method method = clazzTwo.getMethod("setAge",Integer.class);

    //public java.lang.Integer demo.qzxxbj.entity.Student.getAge()
    System.out.println(method);

    //根据方法名以及参数名称获取该类声明的所有的属性方法,不包括父类的
    Method deMethod = clazzTwo.getDeclaredMethod("setAge", Integer.class);

    System.out.println(deMethod);

    //获取该对象声明的所有的public方法,包括父类的
    Method methods[] = clazzTwo.getMethods();

    //获取该对象声明的所有的方法,但是不包含父类的方法
    Method deMethods[] = clazzTwo.getDeclaredMethods();

メソッドをプリントアウトするためにどのような方法は、それですか?上記のコードも含まれています

public void demo.qzxxbj.entity.Student.setAge(java.lang.Integer)

そして、フィールドの前に話すは非常に類似していません。
今の方法は、それは確かに含まれていますメソッド呼び出しを、私たちはこれらのメソッドを取得し、どのように私はそれを行うにはどの方法このクラスを呼び出す必要がありますか?「コールする。」の機能が含まれたinvokeメソッドのクラス、英語を知るための良い、中国の手段のこの呼び出しに、関数invokeを使用します
どのようにそれを使用するには?

    //获取Class第二种方法
    Class clazzTwo = Student.class;
    //根据方法名以及参数类型获取,只能获取public声明的方法,包括父类的
    Method method = clazzTwo.getMethod("setAge",Integer.class);

    //public java.lang.Integer demo.qzxxbj.entity.Student.getAge()
    System.out.println(method);

    //利用Class创建一个对象的实例
    Student student = (Student) clazzTwo.newInstance();

    //函数调用
    Object value = method.invoke(student,20);
    //null
    System.out.println(value);

あなたが理解できないことがあり、上記のコードは、私が最初にすべての、私たちはクラスのクラスを取得し、その後、私たちはsetAgeこのクラスによってこのような方法を取得し、について話しています、メソッドを呼び出し、このメソッドを得た後、このメソッドを呼び出すために続けそれは、メソッド内のオブジェクトのインスタンスと呼ばれるべきではないですか?我々は、それは、()、のnewInstanceの内部を通って、クラスのインスタンスを作成するどのような方法でオブジェクトをインスタンス化する必要があるので、このメソッドは、クラスのインスタンスが、パラメータなしのコンストラクタを持つ必要です。インスタンスを作成するための他の方法がありますが、我々は後に言うでしょう。あなたがオブジェクトのインスタンスを作成した後、我々は、メソッドを呼び出すために始めることができます。
呼び出しメソッドの呼び出しによって、呼び出しの最初のパラメータは、オブジェクトのインスタンスであるか、私はこの方法を探しに行きます。すべてのパラメータが私の後ろにある第二引数、または第三、というように、呼び出しはOKを満たすために行くことに応じて、パラメータを持っています。関数はObjectオブジェクトを返します。その後、あなたは考えることができ、私はものを返す必要がこれらの事を行うには、方法は彼が何かを作ることではありません呼び出し、私は、オブジェクトを使用するようにする事を取得し、この事が何であるかを知りません。私たちは、このメソッドを呼び出しているので、戻り値を必要とするので、nullでは、ありません。それは簡単ではありません。

で、クラスのコンストラクタを取得

これは、すべての後、私は比較的小さな割合の使用を考える、学ぶために最後に私です。一緒にクラスで構成方法を取得する方法を学び、彼を呼び出します。

public Student(String name, int id) {
    this.name = name;
    this.id = id;
}

ここでは、コンストラクタを追加Studentクラスです。

その後、我々はコンストラクタに着きます。

	//获取Class第二种方法
    Class clazzTwo = Student.class;

    //获取无参构造方法,public声明的,包括父类,加上参数时就是获取特定的构造方法
    Constructor constructor = clazzTwo.getConstructor();

    //public demo.qzxxbj.entity.Student()
    System.out.println(constructor);

    //获取该类所有的public声明的构造方法
    Constructor constructors[] = clazzTwo.getConstructors();

    //获取指定参数的构造方法
    Constructor deConstructor = clazzTwo.getDeclaredConstructor(String.class,Integer.class);

    //获取所有的该类的构造方法,不包括父类的
    Constructor deConstructors[] =clazzTwo.getDeclaredConstructors();

上記のコードは理解しやすいべきである、と私は手の込んだことはありません。ここでは、定義により、取得したコンストラクタを使用する方法についての話に我々はそれがクラスを介してオブジェクトをインスタンス化する方法に出たときに、聞かせてのは、二乗法を構築することにより、オブジェクトをインスタンス化してい上に、オブジェクトをインスタンス化するコンストラクタです

	Student student = (Student) deConstructor.newInstance("全栈学习笔记",21);

    //21
    System.out.println(student.getAge());

今、私たちが終わっ機能の貧弱な反射ではない、それを知って、彼はこれがより重要である、ダイナミックプロキシの反射を送信し、ブログは特殊なコードワードが容易ではないだろう。私は信者を指すようにしたいです。マイクロチャンネル公共番号:フルスタックの研究ノート、あなたのためのエッセイ素敵な一日をプッシュ。

最後に、私は私自身の過去の経験の反射をステッチJavaのSQL文を書いて、同等のは、それの反射を応用したものです。

アプリケーション例は、反射しました

動的に生成されたSQL文に反射することで、それは少し速いハードウェアを感じていないのですか?
直接コードを、と私は、私は完全なコードを取得できますSQLステートメント、および興味のある民間の手紙を作りましたよ!

public  String insert(Object object) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {`
    //insert into student(id,name,sex) values (1,"全栈学习笔记","男")
    StringBuilder sql = new StringBuilder();
    Class clazz = object.getClass();
    sql.append("insert into ");

    sql.append(clazz.getSimpleName()+"(");
    Field[] fields = clazz.getDeclaredFields();
    for(Field field:fields){
        sql.append(field.getName()+",");
    }
    sql.deleteCharAt(sql.length()-1);
    sql.append(")");
    sql.append(" values (");
    for(Field field:fields){
        field.setAccessible(true);
       Object value = field.get(object);

       String fieldName = field.getName();
       String str1 = fieldName.substring(0,1).toUpperCase();
       String str2 = fieldName.substring(1,fieldName.length());
       String strValue = str1.concat(str2);
		//String strValue = fieldName.substring(0,1).toUpperCase().concat(fieldName.substring(1,fieldName.length()));
       Method method = clazz.getMethod("get"+strValue,null);

       Object value1 = method.invoke(object,null);

//     if(value1.getClass().equals(String.class))
//     if(field.getType().equals(String.class))
        if(value1 instanceof String){
            sql.append("\"").append(value1).append("\"").append(",");
        }else {
            sql.append(value1).append(",");
        }
    }
    sql.deleteCharAt(sql.length()-1);
    sql.append(")");
    System.out.println(sql.toString());
    return sql.toString();
}

この問題は、あなたが間違った場所にある記事を見つけた場合にも、注釈についての記事を取り消す必要があり、ここで説明する、ああに指摘してください!あなたは多くの知識を学ぶことができると考えられる場合は、懸念ああのポイントを作ります!前方へようこそ!より多くの友人が学ぶしてください!

リリース7件のオリジナルの記事 ウォンの賞賛2 ビュー521

おすすめ

転載: blog.csdn.net/enxiaobai123/article/details/105193822