HOWTO · Java

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

この記事では、リフレクションと Java での使用方法を紹介します。

このページの内容

このチュートリアルでは、リフレクションと Java での使用方法を紹介します。Java には、クラスやインターフェースなどを検査および変更できるリフレクション API 機能があります。

このチュートリアルでは、リフレクション API とは何かとその使用法を学びます。Java でのリフレクションを使用すると、コンパイル時にクラス名がわからなくても、実行時にクラス、インターフェイス、コンストラクター、メソッド、およびフィールドを監視および変更できます。

新しいオブジェクトの作成、メソッドの呼び出し、およびフィールド値の取得/設定はすべて、リフレクションを使用して実行できます。いくつかの例で理解しましょう。

リフレクション API を使用するには、最初に次のパッケージをインポートする必要があります。

java.lang.reflect.*

リフレクション API に含まれるすべてのクラスをインポートします。

クラスオブジェクト

パッケージをインポートした後、リフレクション API メソッドを使用するためのクラスオブジェクトを作成する必要があります。

クラスは、実行時にオブジェクトとクラスに関するすべてのデータを追跡するため、Java に存在します。リフレクションは、Class オブジェクトで実行できます。

クラスオブジェクトは、3つの方法で作成できます。それぞれの方法を 1つずつ見ていきます。

ただし、その前に、このチュートリアル全体で使用するクラスを作成しましょう。

class Furniture {
  public String name;
  private int price;

  public Furniture(String name, int price) {
    this.name = name;
    this.price = price;
  }

  public void update_price(int up_price) {
    this.price = up_price;
  }

  private float cal_discount(int discount) {
    float discounted_price = (1 - discount / 100) * this.price;
    return discounted_price;
  }
}

それでは、家具クラスのクラス Class のオブジェクトを作成しましょう。

Java のクラス forName() メソッド

クラスクラスは、オブジェクトをロードするためのメソッド forName() を提供します。

このメソッドを使用するには、反映するクラスの名前を知っている必要があります。次に、クラス名を引数として forName() メソッドに渡します。

以下のコードを見てください。

Class class
= Class.forName("Furniture");

Java がクラスを見つけられない場合、このメソッドは ClassNotFoundException をスローします。

Java のクラス getClass() メソッド

反映したいクラスのオブジェクトでこのメソッドを呼び出します。このメソッドは、オブジェクトのクラスを返します。

以下のコードを見てください。

Furniture furniture = new Furniture("Chair", 8565);
Class f = furniture.getClass();

.class 機能を使用して、リフレクション用のクラスオブジェクトを取得することもできます。

// create a class object to relect on furniture
Class f = Furniture.class;

Java でのリフレクションに役立つメソッド

クラスオブジェクトには次の 3つのメソッドがあり、これらを使用してクラスを反映できます。

  • getName():このメソッドはクラスの名前を返します。
  • getModifiers():このメソッドは、クラスのアクセス修飾子を表す整数を返します。次に、Modifier.toString() メソッドを使用して、この整数を文字列に変換できます。
  • getSuperclass():このメソッドは、メソッドのスーパークラスを返します。

これらのメソッドを理解するための例を見てみましょう。

import java.lang.reflect.Modifier;
public class SimpleTesting {
  public static void main(String[] args) {
    // create an object of furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // get the name of the class
    String class_name = f.getName();
    System.out.println("The class name is " + class_name);

    // get the class modifier
    int f_modifier = f.getModifiers();
    String f_mod = Modifier.toString(f_modifier);
    System.out.println("The modifier of the class is " + f_mod);

    // get the superclass of the class
    Class f_superclass = f.getSuperclass();
    System.out.println("The Superclass of the class is " + f_superclass.getName());
  }
}

出力:

The class name is Furniture
The modifier of the class is
The Superclass of the class is java.lang.Object

メソッドを反映するための便利なメソッド

Java には、リフレクション中にメソッドを処理する Method というクラスが用意されています。

getDeclaredMethods() というメソッドは、クラスで定義されているすべてのメソッドの配列を返します。返されるメソッドは、クラス Method に属します。

Method クラスには、クラス内のメソッドに関する情報を取得するためのいくつかのメソッドが含まれています。メソッドクラスの次のメソッドを使用します。

  • Method.getName():このメソッドはメソッドの名前を返します。
  • Method.getModifiers():このメソッドは、メソッドのアクセス修飾子を表す整数を返します。
  • Method.getReturnType():このメソッドは、メソッドの戻り型を返します。

これらのメソッドを理解するための例を見てみましょう。

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) {
    // create an object of furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // get all the declared methods of Furniture
    Method[] f_methods = f.getDeclaredMethods();

    for (Method f_method : f_methods) {
      // get the name of the method
      System.out.println("Method Name: " + f_method.getName());

      // get the access modifier of methods
      int f_modifier = f_method.getModifiers();
      System.out.println("Modifier: " + Modifier.toString(f_modifier));

      // get the return type of the methods
      System.out.println("Return Types: " + f_method.getReturnType());
      System.out.println(" ");
    }
  }
}

出力:

Method Name: update_price
Modifier: public
Return Types: void

Method Name: cal_discount
Modifier: private
Return Types: float

上記の例では、Furniture クラスで定義されたメソッドについて知りたいと思っています。まず、getClass() メソッドを使用して Class オブジェクトを作成する必要があります。

フィールドに反映するための便利な方法

Field クラスのメソッドを使用して、クラスのさまざまなフィールドを検査および変更することもできます。と呼ばれるメソッドがあります。

class.getField
(<field name>)

このメソッドは 1つの引数を取ります。アクセスするフィールドの名前であり、渡されたフィールドの Field オブジェクトを返します。次に、Field クラスオブジェクトを使用してさまざまなメソッドを呼び出すことができます。

Field クラスの次のメソッドを使用します。

  • Field.set():このメソッドは、フィールドの値を設定します。
  • Field.get():このメソッドは、フィールドに格納されている値を返します。
  • Field.getModifier():このメソッドは、フィールドのアクセス修飾子を表す整数を返します。

これらのメソッドを理解するための例を見てみましょう。

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) throws Exception {
    // create object of the furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to relect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // acces the name field of Furniture
    Field f_name = f.getField("name");

    // get the value of the field
    String f_name_value = (String) f_name.get(furniture);
    System.out.println("Field value before changing: " + f_name_value);

    // changing the field value
    f_name.set(furniture, "Table");

    // get the value of the field
    f_name_value = (String) f_name.get(furniture);
    System.out.println("Field value after changing: " + f_name_value);

    // get the access modifier
    int f_name_mod = f_name.getModifiers();

    // convert the access modifier to String form
    String f_name_modifier = Modifier.toString(f_name_mod);
    System.out.println("Modifier: " + f_name_modifier);
    System.out.println(" ");
  }
}

出力:

Field value before changing: Chair
Field value after changing: Table
Modifier: public

プライベートフィールドへのアクセスは、メソッド setAccessible() を使用して引数として true を渡すことにより、プライベートフィールドのアクセシビリティを変更する必要があることを除いて、同様です。

以下のサンプルコードを見てください。家具クラスのプライベートフィールド価格にアクセスして変更しようとしています。

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class SimpleTesting {
  public static void main(String[] args) throws Exception {
    // create object of the furniture class
    Furniture furniture = new Furniture("Chair", 8565);
    // create a class object to reflect on furniture
    Class f = furniture.getClass();

    // using object f of Class to
    // access the price field of Furniture
    Field f_price = f.getDeclaredField("price");

    // modifying the accessibility
    f_price.setAccessible(true);

    // get the value of the field
    int f_price_value = (Integer) f_price.get(furniture);
    System.out.println("Field value before changing: " + f_price_value);

    // changing the field value
    f_price.set(furniture, 453);

    // get the value of the field
    f_price_value = (Integer) f_price.get(furniture);
    System.out.println("Field value after changing: " + f_price_value);

    // get the access modifier
    int f_price_mod = f_price.getModifiers();

    // convert the access modifier to String form
    String f_price_modifier = Modifier.toString(f_price_mod);
    System.out.println("Modifier: " + f_price_modifier);
    System.out.println(" ");
  }
}

出力:

Field value before changing: 8565
Field value after changing: 453
Modifier: private

まとめ

この記事を読んだ後、Java でのリフレクションについて十分に理解しました。

また、リフレクションに使用される Java のクラスとメソッドについても学習しました。クラスの名前とそのメソッドおよびフィールドを取得する方法を学びました。

リフレクション API を使用すると、クラスに関する情報をすばやく取得できます。