ホームページ  >  記事  >  Java  >  Javaのリフレクションとは何ですか

Javaのリフレクションとは何ですか

青灯夜游
青灯夜游オリジナル
2021-04-13 17:34:1018327ブラウズ

Java では、リフレクションとは主に、プログラムが自身の状態や動作にアクセスし、検出し、変更する機能を指します。 Java リフレクション メカニズムの主な機能: 1. 実行時にオブジェクトが属するクラスを決定する; 2. 実行時に任意のクラスのオブジェクトを構築する; 3. 実行時に任意のオブジェクトのメソッドを呼び出すなど。

Javaのリフレクションとは何ですか

#このチュートリアルの動作環境: Windows7 システム、Java8 バージョン、DELL G3 コンピューター。

リフレクションとは何ですか?

主に、プログラムが自身の状態や動作にアクセス、検出、変更する機能を指します

Java リフレクション?

Java ランタイム環境では、どのクラスについても、このクラスにどのようなプロパティとメソッドがあるかわかりますか?任意のオブジェクトに対して、そのメソッドを呼び出すことができますか?

Java リフレクション メカニズムは、主に次の機能を提供します:

* 1. 実行時にオブジェクトが属するクラスを決定します。

* 2. 実行時に任意のクラスのオブジェクトを構築します。

* 3. 実行時に任意のクラスのメンバー変数とメソッドを決定します。

* 4. 実行時に任意のオブジェクトのメソッドを呼び出します。


Reflectio

Reflection は、動的 (または準動的) 言語とみなされている Java の重要なプロパティです。

このメカニズムにより、プログラムは実行時にリフレクション API を通じて既知の名前を持つクラスの内部情報を取得できます。

修飾子 (public、static など)、スーパークラス (Object など)、実装されたインターフェイス (Serializable など)、およびそのフィールドとメソッドに関するすべての情報が含まれており、その内容を変更できます。実行時のフィールドまたはメソッドの呼び出し。

動的言語

動的言語の定義 「プログラムの実行中に、プログラムの構造や変数の型を変更することができます。この言語は動的言語と呼ばれます」言語。"

この観点から見ると、Perl、Python、Ruby は動的言語ですが、C、Java、C# は動的言語ではありません。

この定義と分類では Java は動的言語ではありませんが、非常に顕著な動的関連メカニズムであるリフレクションを備えています。この単語の意味: リフレクション、イメージ、リフレクション Java で使用される場合、コンパイル中にはまったく不明なクラスを実行時にロード、検出、使用できることを意味します。

つまり、Java プログラムは、名前が実行時にのみ判明するクラスをロードし、その完全な構造 (ただしメソッド定義は含まない) を学習して、そのオブジェクト エンティティを生成したり、そのクラスの値を設定したりできます。フィールド、またはそのメソッドを呼び出します。

プログラム自体を検査する機能は、イントロスペクションと呼ばれます。反省と内省は、よく一緒に言及される 2 つの用語です。

Java リフレクション API の概要

JDK では、Java リフレクション メカニズムは主に次のクラスによって実装されます。これらのクラス (最初のクラスを除く) はすべて次の場所にあります。 java.lang.reflect パッケージ内の

クラス class: クラスを表し、java.lang パッケージの下にあります。

フィールド クラス: クラスのメンバー変数を表します (メンバー変数はクラスの属性とも呼ばれます)。

メソッド クラス: クラスのメソッドを表します。

コンストラクター クラス: クラスの構築メソッドを表します。

Array クラス: 配列を動的に作成し、配列要素にアクセスするための静的メソッドを提供します。

クラス オブジェクト

リフレクションを使用するには、まず操作対象のクラスに対応する Class オブジェクトを取得する必要があります。

Java では、特定のクラスのオブジェクトがいくつ生成されても、それらのオブジェクトは同じ Class オブジェクトに対応します。

この Class オブジェクトは JVM によって生成され、それを通じてクラス全体の構造を学習できます。

Class オブジェクトを取得するためによく使用される 3 つの方法:

1. Class クラスの静的メソッドを使用します。例:

Class.forName(“java.lang.String”);

2. クラスの .class 構文を使用します。例:

String.class;

3. オブジェクトの getClass() メソッドを使用します。例:

String str = “aa”; 
Class

ルーチン 1: メソッドの取得

ルーチン DumpMethods クラスは、Reflection API の基本機能を示します。コマンドラインパラメータで指定されたクラス名と、このクラスのメソッド情報を出力します。

import java.lang.reflect.Method;
 
public class DumpMethods
{
    public static void main(String[] args) throws Exception //在方法后加上这句,异常就消失了
    {
        //获得字符串所标识的类的class对象
        Class<?> classType = Class.forName("java.lang.String");//在此处传入字符串指定类名,所以参数获取可以是一个运行期的行为,可以用args[0]
 
        //返回class对象所对应的类或接口中,所声明的所有方法的数组(包括私有方法)
        Method[] methods = classType.getDeclaredMethods();
 
        //遍历输出所有方法声明
        for(Method method : methods)
        {
            System.out.println(method);
        }
    }
 
}

ルーチン 2: リフレクションを介したメソッドの呼び出し

リフレクションを介してメソッドを呼び出します。詳細については、コードとコメントを参照してください。

import java.lang.reflect.Method;
 
public class InvokeTester
{
    public int add(int param1, int param2)
    {
        return param1 + param2;
 
    }
 
    public String echo(String message)
    {
        return "Hello: " + message;
    }
 
    public static void main(String[] args) throws Exception
    {
 
        // 以前的常规执行手段
        InvokeTester tester = new InvokeTester();
        System.out.println(tester.add(1, 2));
        System.out.println(tester.echo("Tom"));
        System.out.println("---------------------------");
 
        // 通过反射的方式
 
        // 第一步,获取Class对象
        // 前面用的方法是:Class.forName()方法获取
        // 这里用第二种方法,类名.class
        Class<?> classType = InvokeTester.class;
 
        // 生成新的对象:用newInstance()方法
        Object invokeTester = classType.newInstance();
        System.out.println(invokeTester instanceof InvokeTester); // 输出true
 
        // 通过反射调用方法
        // 首先需要获得与该方法对应的Method对象
        Method addMethod = classType.getMethod("add", new Class[] { int.class,
                int.class });
        // 第一个参数是方法名,第二个参数是这个方法所需要的参数的Class对象的数组
 
        // 调用目标方法
        Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 });
        System.out.println(result); // 此时result是Integer类型
 
        //调用第二个方法
        Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class});
        Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"});
        System.out.println(result2);
 
    }
}

オブジェクトの生成

パラメータのないクラスのコンストラクター メソッドを通じてオブジェクトを生成する場合、次の 2 つの方法があります。

1. 最初に Class オブジェクトを取得し、次に Class オブジェクトの newInstance() メソッドを通じてそれを直接生成します:

 Class<?> classType = String.class;
 
 Object obj = classType.newInstance();

2. 最初に Class オブジェクトを取得してから、対応する次に、Constructor オブジェクトの newInstance() メソッドを通じて

を生成します (Customer は、パラメーターなしのコンストラクターとパラメーター化されたコンストラクターを持つカスタム クラスです):

    Class<?> classType = Customer.class;
 
    // 获得Constructor对象,此处获取第一个无参数的构造方法的
    Constructor cons = classType.getConstructor(new Class[] {});
 
    // 通过构造方法来生成一个对象
    Object obj = cons.newInstance(new Object[] {});

クラスのパラメーター化されたコンストラクターを通じてオブジェクトを生成したい場合は、次のメソッドのみを使用できます:

(顧客はパラメーターなしのコンストラクターとパラメーター化されたコンストラクターを持つカスタム クラスです。メソッド、文字列と整数を渡します)

    Class<?> classType = Customer.class;
 
    Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});
 
    Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});

可以看出调用构造方法生成对象的方法和调用一般方法的类似,不同的是从Class对象获取Constructor对象时不需要指定名字,而获取Method对象时需要指定名字。

相关视频教程推荐:Java视频教程

以上がJavaのリフレクションとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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