ホームページ  >  記事  >  Java  >  クラスとオブジェクトの情報を取得するための Java リフレクションの詳細な紹介

クラスとオブジェクトの情報を取得するための Java リフレクションの詳細な紹介

黄舟
黄舟オリジナル
2017-03-28 10:51:531685ブラウズ

リフレクションは、オブジェクトがどのクラスに属するかコンパイル時に予測できず、オブジェクト

やクラスの情報はプログラム実行時の情報でしか分からないという問題を解決することができます。

2人で共同開発する場合、相手のクラス名を知るだけで事前開発が行えます。

クラスオブジェクトを取得します
  • Class.forName(String clazzName)静的メソッド
  • クラスのクラス属性を呼び出します
  • Person.classは、Personのクラスオブジェクトを返します(推奨)

オブジェクトを呼び出しますgetClass() メソッド

は、クラス名を知るだけで比較的自由です。2 番目と 3 番目のメソッドは検証を実行しません。

    クラス情報を取得する
  • クラス コンストラクターを取得するConnstructor8742468051c85b06f0a0af9e3e506b5c getConstructor(Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes):返回此Class对象对应类的带指定形参的public构造器

  • Constructor6b3d0130bba23ae47fe2b8e8cddf0195[] getConstructors():返回此Class对象对应类的所有public构造器

  • Constructor8742468051c85b06f0a0af9e3e506b5c[] getDeclaredConstructor(Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes):返回此class对象对应类的带指定参数的构造器,与构造器的访问权限无关

  • Constructor6b3d0130bba23ae47fe2b8e8cddf0195[] getDeclaredConstructors():返回此class对象对应类的所有构造器,与构造器的访问权限无关

获取类成员方法

  • Method getMethod(String name,Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes):返回此class对象对应类的带指定形参的public方法

  • Method[] getMethods():返回此class对象所表示的类的所有public方法

  • Method getDeclaredMethod(string name,Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes):返回此class对象对应类的带指定形参的方法,与方法访问权限无关

  • Method[] getDeclaredMethods():返回此class对象对应类的全部方法,与方法的访问权限无关

获取类成员变量

  • Field getField(String name):返回此class对象对应类的指定名称的public成员变量

  • Field[] getFields():返回此class对象对应类的所有public成员变量

  • Field getDeclaredField(String name):返回此class对象对应类的指定名称的成员变量,与成员变量访问权限无关

  • Field[] getDeclaredFields():返回此class对象对应类的全部成员变量,与成员变量的访问权限无关

获取类注解

  • ff56b21ab54c6b5c37cb9b57f821804eA getAnnotation(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass):尝试获取该class对象对应类上村子的指定类型的Annotation,如果该类型注解不存在,则返回null

  • ff56b21ab54c6b5c37cb9b57f821804eA getDeclaredAnnotation(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass):这是Java 8中新增的,该方法获取直接修饰该class对象对应类的指定类型的Annotation,如果不存在,则返回null

  • Annotation[] getAnnotations():返回修饰该class对象对应类上存在的所有Annotation

  • Annotation[] getDeclaredAnnotations():返回修饰该Class对象对应类上存在的所有Annotation

  • ff56b21ab54c6b5c37cb9b57f821804eA[] getAnnotationByType(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass):该方法的功能与前面介绍的getAnnotation()方法基本相似,但由于Java8增加了重复注解功能,因此需要使用该方法获取修饰该类的指定类型的多个Annotation

  • ff56b21ab54c6b5c37cb9b57f821804eA[] getDeclaredAnnotationByType(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass):该方法发功能与前面介绍的getDeclaredAnnotations()方法相似,也是因为Java8的重复注解的功能,需要使用该方法获取直接修饰该类的指定类型的多个Annotation

获取该类内部类

  • Class6b3d0130bba23ae47fe2b8e8cddf0195[] getDeclaredClasses():返回该class队形对应类里包含的全部内部类

获取该类对象所在的外部类

  • Class6b3d0130bba23ae47fe2b8e8cddf0195 getDeclaringClass():返回该Class对象对应类所在的外部类

获取该类对象对应类所实现的接口

  • Class6b3d0130bba23ae47fe2b8e8cddf0195[] getInterfaces()

    🎜🎜Connstructor8742468051c85b06f0a0af9e3e506b5c getConstructor(Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes): 対応するクラスの指定された仮パラメーターを持つパブリック コンストラクターを返します。この Class オブジェクトの🎜🎜🎜🎜Constructor6b3d0130bba23ae47fe2b8e8cddf0195[] getConstructors(): この Class オブジェクトの対応するクラスのすべてのパブリック コンストラクターを返します 🎜🎜🎜🎜Constructor8742468051c85b06f0a0af9e3e506b5c[ ] getDeclaredConstructor(Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes): このクラス オブジェクトの対応するクラスの指定されたパラメーターを持つコンストラクターと、コンストラクターのアクセス権を返します。 ?>[] getDeclaredConstructors(): コンストラクターのアクセス権に関係なく、このクラス オブジェクトの対応するクラスのすべてのコンストラクターを返します🎜🎜🎜🎜クラス メンバーのメソッドを取得します🎜 🎜🎜🎜Method getMethod (String name,Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes): このクラス オブジェクトの対応するクラスの指定された仮パラメータを持つパブリック メソッドを返します🎜🎜🎜🎜Method[ ] getMethods() code>: このクラス オブジェクトによって表されるクラスのすべてのパブリック メソッドを返します 🎜🎜🎜🎜<code>Method getDeclaredMethod(string name,Class6b3d0130bba23ae47fe2b8e8cddf0195...parameterTypes): Return このクラス オブジェクトは、クラスの指定された仮パラメータを持つメソッドであり、メソッドのアクセス権とは何の関係もありません🎜🎜🎜🎜Method[] getDeclaredMethods(): このクラス オブジェクトに対応するクラスのすべてのメソッドとメソッドを返します。 access 権限は関係ありません🎜🎜🎜🎜クラスのメンバー変数を取得します🎜🎜🎜🎜Field getField(String name): このクラスオブジェクトに対応する指定された名前のパブリックメンバー変数を返します🎜🎜🎜🎜Field[ ] getFields(): このクラス オブジェクトに対応するクラスのすべてのパブリック メンバー変数を返します🎜🎜🎜🎜Field getDeclaredField(String name): 指定されたクラスのメンバー変数を返しますこのクラス オブジェクトに対応するクラスの名前。メンバー変数のアクセス権とは関係ありません🎜🎜🎜🎜Field[] getDeclaredFields(): このクラスの対応するクラスのすべてのメンバー変数を返しますオブジェクトは、メンバー変数のアクセス権とは何の関係もありません🎜🎜🎜🎜クラスのアノテーションを取得します🎜🎜🎜🎜ff56b21ab54c6b5c37cb9b57f821804eA getAnnotation(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass): 取得を試みますクラス オブジェクトの対応するクラスの指定された型の注釈。型注釈が存在しない場合は、null を返します🎜🎜🎜🎜ff56b21ab54c6b5c37cb9b57f821804eA getDeclaredAnnotation(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass) code>: これは Java 8 の新機能です。このメソッドは、クラス オブジェクトを直接変更する対応するクラスの指定を取得します。Annotation の型が存在しない場合は、null🎜🎜🎜🎜<code>Annotation[] getAnnotations を返します。 (): クラス オブジェクトを変更する、対応するクラスに存在するすべてのアノテーションを返します🎜🎜🎜🎜Annotation[ ] getDeclaredAnnotations(): すべてのアノテーションを返します🎜🎜🎜🎜 ff56b21ab54c6b5c37cb9b57f821804eA[] getAnnotationByType(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass): このメソッドの機能は基本的に前に紹介した getAnnotation() メソッドと似ていますが、Java8 では反復アノテーション関数が追加されているため、このメソッドを使用して、クラスの指定された型を変更する複数のアノテーションを取得するには🎜🎜🎜🎜ff56b21ab54c6b5c37cb9b57f821804eA[] getDeclaredAnnotationByType(Class72d4ced2cc960a6bc2541984146fdaaaannotationClass): このメソッドの機能これは、以前に紹介した getDeclaredAnnotations() メソッドと似ていますが、これは Java8 の繰り返しアノテーション機能のため、クラスの指定された型の複数のアノテーションを直接取得する必要があります🎜🎜🎜。 🎜クラスの内部クラスを取得します🎜🎜🎜🎜Class6b3d0130bba23ae47fe2b8e8cddf0195[] getDeclaredClasses(): クラス形成の対応するクラスに含まれるすべてのクラスを返します 内部クラス🎜🎜🎜🎜Getこのクラスのオブジェクトが配置されている外部クラス🎜🎜🎜🎜Class6b3d0130bba23ae47fe2b8e8cddf0195 getDeclaringClass(): Class オブジェクトの対応するクラスが配置されている外部クラスを返します🎜🎜🎜🎜Getクラス オブジェクトの対応するクラスによって実装されたインターフェイス🎜🎜🎜🎜Class6b3d0130bba23ae47fe2b8e8cddf0195[] getInterfaces(): Class オブジェクトの対応するクラスによって実装されたすべてのインターフェイスを返します🎜

このクラスオブジェクトの対応するクラスによって継承された親クラスを取得します

  • Class45f0d2e7f3b82b5d36687301332d1b46 getSuperclass():返回该Class对象对应类的超类的Class对象

获取该类对象对应类的修饰符、所在包、类名等基本信息

  • int getModifiers():返回此类或接口的所有修饰符,修饰符由public、protected、private、final、static、abstract等对应的常量组成,返回的整数应使用Modifier工具类的方法来解码,才可以获取真是的修饰符

  • Package getPackage():获取该类的包

  • String getName():以字符串形式返回此CLass对象所表示的类的简称

判断该类是否为接口、枚举、注解类型

  • boolean isAnnotation():返回此class对象是否表示一个注解类型

  • boolean isAnnotationPresent(Classe7efc8cbc31a41b0598dead74d6893ddannotationClass):判断此Class对象是否使用类Annotation修饰

  • boolean isAnonymousClass():返回此class对象是否是一个匿名类

  • boolean isArray():返回此class对象是否表示一个数组

  • boolean isEnum():返回此class对象是否表示一个枚举

  • boolean isInterface():返回此class对象是否表示一个接口

  • boolean isInstance(<a href="http://www.php.cn/wiki/60.html" target="_blank">Object</a> obj):判断obj是否是此class对象的实例,该方法可以完全代替instanceof操作符

public interface Colorable {
     public void value();
}
public class ClassInfo {

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        Class<Colorable> cls=Colorable.class;
        System.out.println(cls.getMethod("value"));
        System.out.println(cls.isAnnotation());
        System.out.println(cls.isInterface());
    }

}

结果

public abstract void com.em.Colorable.value()
false
true

Java8中新增的方法参数反射

  • int getParameterCount():获取该构造器或方法的形参个数

  • Parameter[] getParameters():获取该构造器或方法的所有形参

  • getModifiers():获取修饰该形参的修饰符

  • String getName():获取形参名

  • Type getParameterizedType():获取带泛型的形参类型

  • Class6b3d0130bba23ae47fe2b8e8cddf0195getType():获取形参类型

  • boolean isNamePresent():该方法返回该类的class文件中是否包含了方法的形参名信息

  • boolean isVarArgs():该方法用于判断该参数是否为个数可变的形参

public class Test {
    public void getInfo(String str,List<String>list){
        System.out.println("成功");
    }
}
public class ClassInfo {

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        Class<Test> cls=Test.class;
        Method med=cls.getMethod("getInfo", String.class,List.class);
        System.out.println(med.getParameterCount());
        Parameter[] params=med.getParameters();
        System.out.println(params.length);
        for(Parameter par:params){
            System.out.println(par.getName());
            System.out.println(par.getType());
            System.out.println(par.getParameterizedType());
        }
    }

}

结果

2
2
arg0
class java.lang.String
class java.lang.String
arg1
interface java.util.List
java.util.List<java.lang.String>

反射生成对象

  • 使用Class对象的newInstance()方法创建Class对象的实例,该方法要求要有默认构造器(比较常用)

  • 先使用Class对象获取指定的Constructor对象,在调用Constructor对象的newInstance()方法来创建该Class对象对应类的实例

反射调用方法

  • Object invoke(Object obj,Object...args):该方法中的obj是执行该方法的主调,后面的args是执行该方法时传入该方法的实参

public class Test {

    public Test(String str) {
        System.out.println(str);
    }
    public void getInfo(String str){
        System.out.println(str);
    }
}
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
        Method med=cls.getMethod("getInfo", String.class);
        med.invoke(test, "调用方法成功");
    }

}

结果

初始化
调用方法成功

接下来看官仔细看下面的栗子

public class Test {

    public Test(String str) {
        System.out.println(str);
    }
    //私有方法
    private void getInfo(String str){
        System.out.println(str);
    }
}
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
      //为啥使用这个方法呢?
        Method med=cls.getDeclaredMethod("getInfo", String.class);
      //为啥使用这个方法呢?
        med.setAccessible(true);
        med.invoke(test, "调用方法成功");
    }

}

结果

初始化
调用方法成功

setAccessible(boolean flag):将值设为true,指示该Method在使用是应该取消Java语言的访问权限检查

访问成员变量值

  • getXxx(Object obj):获取obj对象的该成员变量的值。此处的Xxx对应8种基本类型,如果该成员变量的类型是引用类型的,则去掉Xxx部分

  • setXxx(Object obj,Xxx val):将obj对象的该成员变量设置为val值。此处的Xxx对应8中基本类型,如果该成员变量的类型是引用类型,则取消set后面的Xxx

以上两个方法可以方法所有的成员变量,包括private的私有成员变量

public class Test {
    private int num;

    public Test(String str) {
        System.out.println(str);
    }
    private void getInfo(String str){
        System.out.println(str);
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }

}
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
        Method med=cls.getDeclaredMethod("getInfo", String.class);
        med.setAccessible(true);
        med.invoke(test, "调用方法成功");
        Field fld=cls.getDeclaredField("num");
        fld.setAccessible(true);
        fld.setInt(test, 12);
        System.out.println(fld.getInt(test));
    }

}

结果

初始化
调用方法成功
12

操作数组

java.lang.reflect包下有一个Array类,其可以动态创建数组

static Object newInstance(Class6b3d0130bba23ae47fe2b8e8cddf0195componentType,int...length)

🎜 🎜このクラス オブジェクトの修飾子、パッケージ、クラス名、その他の対応するクラスなどの基本情報を取得します🎜🎜🎜🎜int getModifiers(): このクラスまたはインターフェイスのすべての修飾子を返します、修飾子は public で構成され、protected、private、final、static、abstract などの対応する定数で構成されます。返される 整数は、モディファイア ツールのクラス メソッドを使用してデコードして実際のモディファイアを取得する必要があります🎜🎜🎜🎜Package getPackage(): このクラスのパッケージを取得します🎜🎜🎜 🎜String getName() code>: この CLAss オブジェクトによって表されるクラスの短縮名を string🎜🎜 🎜🎜クラスがインターフェイス、列挙型、または注釈型であるかどうかを判断します🎜🎜🎜🎜boolean isAnnotation(): このクラスがインターフェイスであるかどうかを返します。オブジェクトは注釈タイプを表します🎜🎜🎜🎜boolean isAnnotationPresent(Class&lt ;? extends Annotation>annotationClass): この Class オブジェクトがクラス Annotation で修飾されているかどうかを決定します🎜🎜🎜🎜boolean isAnonymousClass(): このクラス オブジェクトが <a href="http://www.php.cn/wiki/193.html" target="_blank">匿名クラス</a>かどうかを返します🎜🎜🎜🎜<code>boolean isArray(): このクラス オブジェクトが Array クラスを表すかどうかを返します。 🎜🎜🎜🎜boolean isEnum(): このクラスオブジェクトが列挙型を表すかどうかを返します🎜🎜🎜🎜boolean isInterface(): このクラスオブジェクトがインターフェイスを表すかどうかを返します🎜🎜 🎜🎜boolean isInstance(<a href="http:/%20/www.php.cn/wiki/60.html" target="_blank">Object</a> obj): obj かどうかを判断します。このクラス オブジェクトのインスタンスです。このメソッドは、instanceofOperator を完全に置き換えることができます🎜🎜🎜
public class ArrayInfo {

    public static void main(String[] args) {
        Object arrays=Array.newInstance(String.class, 3);
        Array.set(arrays, 0, "第一个");
        Array.set(arrays, 1, "第二个");
        Array.set(arrays, 2, "第三个");
        System.out.println(Array.get(arrays, 2));
    }
}
rrreee 🎜Result🎜rrreee

Java8 新しいメソッドパラメータリフレクション

🎜🎜🎜int getParameterCount(): コンストラクターまたはメソッドの仮パラメータの数を取得します🎜 🎜🎜🎜Parameter[] getParameters(): コンストラクターまたはメソッドのすべての仮パラメーターを取得します🎜🎜🎜🎜<code>getModifiers(): 仮パラメーターを変更する修飾子を取得します🎜🎜🎜🎜String getName() code>: 正式なパラメータ名を取得します🎜🎜🎜🎜<code>Type getParameterizedType(): 汎用パラメータの型を取得します🎜🎜🎜🎜Class&lt ;?>getType() : 仮パラメータの型を取得します🎜🎜🎜🎜boolean isNamePresent(): このメソッドは、クラスのクラス ファイルに次の仮パラメータ名の情報が含まれているかどうかを返します。メソッド🎜🎜🎜🎜boolean isVarArgs() : このメソッドは、パラメータが可変数の仮パラメータであるかどうかを判断するために使用されます🎜🎜🎜rrreeerrreee🎜Result🎜rrreeeリフレクション生成オブジェクト🎜🎜🎜使用 Class オブジェクトの newInstance() メソッドは、Class オブジェクトのインスタンスを作成します。このメソッドには、デフォルトのコンストラクター (より一般的に使用される) が必要です。🎜🎜🎜🎜最初に Class オブジェクトを使用します。指定された Constructor オブジェクトを取得し、Constructor オブジェクトの newInstance() メソッドを呼び出してそれを作成します。 Class オブジェクトは、クラスのインスタンスに対応します🎜🎜🎜

Reflection 呼び出しメソッド

🎜🎜🎜Object invoke(Object obj,Object...args): このメソッドの obj が実行されます このメソッドの主な呼び出しである次の引数は、メソッドの実行時にメソッドに渡される実際のパラメータです🎜🎜🎜rrreeerrreee 🎜Result🎜rrreee🎜次に、読者は下の栗を詳しく見てみましょう🎜rrreeerrreee🎜Result🎜rrreee
🎜setAccessible(boolean flag): 値を設定しますtrue に設定すると、この Method🎜

Access member variables Value

🎜🎜🎜getXxx(Object obj) を使用するときに Java 言語のアクセス許可チェックをキャンセルする必要があることを示します。 objオブジェクトのメンバー変数の値を取得します。ここでの Xxx は 8 つの基本型に対応します。メンバー変数の型が 参照 型の場合、次に、Xxx 部分を削除します🎜🎜🎜🎜setXxx(Object obj,Xxx val): obj オブジェクトのメンバー変数を val 値に設定します。ここでのXxxは、メンバー変数の型が参照型の場合、set🎜🎜🎜
の後にXxxをキャンセルします🎜上記の2つのメソッドは、プライベートプライベートメンバー変数を含むすべてのメンバー変数にアクセスできます🎜
rrreeerrreee🎜結果🎜rrreee

操作配列

🎜 java.lang.reflect パッケージの下には配列を動的に作成できる Array クラスがあります🎜🎜 static Object newInstance(Class6b3d0130bba23ae47fe2b8e8cddf0195componentType,int...length): 指定された要素タイプと指定された次元で新しい配列を作成します🎜

static xxx getXxx(Object array,int index):返回array数组中第index个元素。其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为get()

static void setXxx(Object array,int index,xxx val):将array数组中低index 个元素的值设为val,其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为set()

public class ArrayInfo {

    public static void main(String[] args) {
        Object arrays=Array.newInstance(String.class, 3);
        Array.set(arrays, 0, "第一个");
        Array.set(arrays, 1, "第二个");
        Array.set(arrays, 2, "第三个");
        System.out.println(Array.get(arrays, 2));
    }
}

以上がクラスとオブジェクトの情報を取得するための Java リフレクションの詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。