Javaの学習のまとめ - 反射

リフレクションは、多くの場合、言葉を聞くが、常にそれが何を意味するのか理解していません。フレームワークの設計では、反射器はより使用なぜ今日は、反射の概念を理解して見てください。この記事では、反射の学習側面についての知識を説明します。

反射の概念

Javaリフレクション機構が作動状態で、任意のクラスのために、このクラスのすべてのプロパティとメソッドに知られて作られている、任意のオブジェクトのために、そのメソッドとプロパティを呼び出すことが可能であり、この情報は、動的に取得して動的呼出し反射機構のJava言語と呼ばれるオブジェクト関数の方法。コンセプトは、より正確であるが、抽象の理解を容易にしません。たとえば、私たちはクラスを提示し、それに関連するプロパティ、メソッド、コンストラクタのタイプは、クラスのために、私たちはそのターゲットに新しい道を作成することはできません、プライベートではなく、起動するために、プロパティの方法を用いて通常の方法でありますこのクラスのプロパティ、メソッド、さらにはそのオブジェクトを作成するが、それは、オブジェクトを反射することによって、このようにして生成し、そのプロパティとメソッドを呼び出すことができます。

クラス

クラスとクラスは、本質的に異なっています。小文字のクラスは、Javaのキーワードで、クラスの首都はクラスです。

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
}
复制代码

Javaの世界では、すべてのものがオブジェクトであり、Javaで2つのオブジェクトがありますが、新しいオブジェクトは、別のクラスのオブジェクトを生成することです。格納されている情報に対応するJVMクラスを生成するために使用されているため、一般のオブジェクトは、我々は、Classオブジェクトはできない、新しいキーワードによって生成することができます。など、他の言葉では、私たちが正常にコンパイルクラスの人を、定義すると、それは我々がClassオブジェクトを作成し、人にそれを保存すると同時に、コンパイラから、この時間をPerson.classバイトコードを生成します。クラスファイル。言い換えれば:Person.classにコンパイルPerson.javaは、対応するClassオブジェクトを生成します。

Classオブジェクトを取得します

一般に、入手するには、次の三つの方法に対応するオブジェクトのクラスのオブジェクトのインスタンス:

図1に示すように、実施例のgetClass変数の方法によって:

Person person = new Person();
Class personClass = person.getClass();
System.out.println("class1: " + personClass);
复制代码

2は、直接の.classファイルオブジェクトクラス与えられました:

Class personClass1=Person.class;
System.out.println("class2: " + personClass1);
复制代码

オブジェクトは、新しいキーワードによって作成することができない場合、我々はまた、第三の方法を介して取得することができます。

図3に示すように、クラスのクラス()の静的メソッドにforNameによって:

try {
          Class personClass2 = Class.forName("reflect.Person");
          System.out.println("class3: " + personClass2);
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      }
复制代码

次のように印刷結果は以下のとおりです。

class1: class reflect.Person
class2: class reflect.Person
class3: class reflect.Person
复制代码

クラスの使用

Javaリフレクション機構が作動状態で、任意のクラスのために、このクラスのすべてのプロパティとメソッドに知られて作られている、任意のオブジェクトのために、そのメソッドとプロパティを呼び出すことが可能であり、この情報は、動的に取得して動的呼出し反射機構のJava言語と呼ばれるオブジェクト関数の方法。

1は、CLASSが名を取得します名前を取得するために、Classクラスは、3つのメソッドを提供します。

Class.getName();
Class.getSimpleName();
Class.getCanonicalName();
复制代码

したがって、これらの3つの方法の違いは何ですか?さらに具体的な実施例により説明。

まず、クラスPerson.javaを作成する必要があります

package reflect;
public class Person {
    private int age;
    private String name;
    public Person() {
    }
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
复制代码

そして、それぞれのクラス名を取得:

      //getName()方式
      Person person = new Person();
      Class personClass = person.getClass();
      System.out.println("class1: " + personClass.getName());
 //getSimpleName()方式
      Class personClass1=Person.class;
      System.out.println("class2: " + personClass1.getSimpleName());
//getCanonicalName()方式
      try {
          Class personClass2 = Class.forName("reflect.Person");
          System.out.println("class3: " + personClass2.getCanonicalName());
      } catch (ClassNotFoundException e) {
          e.printStackTrace();
      }
复制代码

次のように印刷結果は以下のとおりです。

class1: reflect.Person
class2: Person
class3: reflect.Person
复制代码

私たちは、最初の結果が得見ることができると三番目の方法は同じですが、唯一の第二は同じではありません。第二は、クラス名を取得することですしながら13取得には、クラスへのフルパスで、パッケージ名が含まれていません。違いは何13種類の内部クラスのクラスによって調査することができます。

2は、修飾子が得る主にプライベート、パブリック、静的、保護、およびその上にあるJavaの修飾子で。これらの修飾子へのアクセスを提供するために、JavaリフレクションAPI。

Class.getModifiersを介して取得する修飾子()

Person person = new Person();
Class personClass = person.getClass();
System.out.println("modifiers: " + personClass.getModifiers());
复制代码

結果は以下の通りであります:

modifiers: 1
复制代码

戻り値の型はint型の値です。なぜ整数値を返しますか?クラス定義は、複数の修飾子かもしれ際のJavaエンジニアは、アカウントにビット演算を取ったように、すべての修飾子を記録するint型の値で、一緒に取得するためには、修正するためです、と異なるビットが異なる修飾子に対応しますこれらの修飾子は、修飾子クラスのうちの対応するビットで定義されています。

public class Modifier {
    public static final int PUBLIC           = 0x00000001;
    public static final int PRIVATE          = 0x00000002;
    public static final int PROTECTED        = 0x00000004;
    public static final int STATIC           = 0x00000008;
    public static final int FINAL            = 0x00000010;
	......
	public static String toString(int mod) {
        StringBuilder sb = new StringBuilder();
        int len;
        if ((mod & PUBLIC) != 0)        sb.append("public ");
        if ((mod & PROTECTED) != 0)     sb.append("protected ");
        if ((mod & PRIVATE) != 0)       sb.append("private ");
        /* Canonical order */
        if ((mod & ABSTRACT) != 0)      sb.append("abstract ");
        if ((mod & STATIC) != 0)        sb.append("static ");
        if ((mod & FINAL) != 0)         sb.append("final ");
        if ((mod & TRANSIENT) != 0)     sb.append("transient ");
        if ((mod & VOLATILE) != 0)      sb.append("volatile ");
        if ((mod & SYNCHRONIZED) != 0)  sb.append("synchronized ");
        if ((mod & NATIVE) != 0)        sb.append("native ");
        if ((mod & STRICT) != 0)        sb.append("strictfp ");
        if ((mod & INTERFACE) != 0)     sb.append("interface ");
        if ((len = sb.length()) > 0)    /* trim trailing space */
            return sb.toString().substring(0, len-1);
        return "";
    }
复制代码

あなたは、文字列を印刷したい場合はもちろん、それを取得するためにモディファイクラスの静的メソッドのtoStringを介して提供することができます。

System.out.println("modifiers: " + Modifier.toString(personClass.getModifiers()));
复制代码

3、の取得クラスメンバークラスのメンバーは、プロパティ、メソッド、コンストラクタが含まれています。これは、クラスのフィールド、メソッド、コンストラクタにマップされます。次は、これらのメンバーに精通取得する方法の具体例を通ってきます。

フィールドを取得する3.1は、属性がAPIの名前を指定します取得します。

public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException;
public Field getField(String name)
               throws NoSuchFieldException,
                      SecurityException
复制代码

違いはgetDeclaredFieldは()修正クラスは私有財産いる得ることです。祖先を取得する非私有財産を取得するためのgetField()メソッド、およびのgetField()クラスは、現在の時刻を取得します未満です。

すべての属性を取得します。

//获取所有的属性,但不包括从父类继承下来的属性
public Field[] getDeclaredFields() throws SecurityException {}

//获取自身的所有的 public 属性,包括从父类继承下来的。
public Field[] getFields() throws SecurityException {}
复制代码

3.2方法、入手方法、すなわち、クラスのメソッドを。

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
public Method getMethod(String name, Class<?>... parameterTypes)
public Method[] getDeclaredMethods() throws SecurityException
public Method getMethod(String name, Class<?>... parameterTypes)
复制代码

3.3、コンストラクタを取得します

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
public Constructor<T> getConstructor(Class<?>... parameterTypes)
public Constructor<?>[] getDeclaredConstructors() throws SecurityException 
public Constructor<?>[] getConstructors() throws SecurityException
复制代码

リフレクションの使用

上記の単純なフィールド法、コンストラクタで取得されたクラスは、これらの制御メカニズムは、フィールド、メソッド、コンストラクタを反映しています。

著者について

Androidの開発に注力長年にわたり、書き込みブログのレコードを好きでは〜、私のブログのパブリック番号、歓迎みんなの注目の同期更新を学習経験について話すことができまとめます

ここに画像を挿入説明

おすすめ

転載: juejin.im/post/5dd3e1836fb9a01fdf7c08ee