English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Java フロー制御

Java 配列

Java オブジェクト指向(I)

Java オブジェクト指向(II)

Java オブジェクト指向(III)

Java 異常処理

Java リスト(List)

Java キュー(キュー)

Java Mapコレクション

Java Setコレクション

Java 入出力(I/O)

Java Reader/Writer

Javaの他のトピック

Java 反射(Reflection)

このチュートリアルでは、Javaプログラミングの特性である反射を学びます。これはクラス、メソッドなどのチェックおよび修正を許可します。

Javaでは、反射を使用して、実行時にクラス、インターフェース、コンストラクタ、メソッド、フィールドをチェックおよび操作できます。

Javaのクラス名はClass

Javaの反射を学ぶ前に、Classという名前のJavaクラスについて理解する必要があります。

Javaには、実行時にオブジェクトとクラスに関するすべての情報を保持するClassという名前のクラスがあります。

Classオブジェクトは特定のクラスの属性を説明し、反射を実行するために使用されます。

Classの名前のクラスのオブジェクトを作成

以下のようにClassのオブジェクトを作成できます:

  • forName()メソッドを使用して

forName()は文字列パラメータ(クラスの名前)を受け取り、Classオブジェクトを返します。返されるオブジェクトは文字列パラメータで指定されたクラスを参照します。例えば、

Class Dog {  }
Class c1 = Class.forName("Dog");
  • getClass()メソッドを使用して

 getClass()メソッドを使用して特定のクラスのオブジェクトを用いて新しいオブジェクトClassを作成します。例えば、

Dog d1 = new Dog()
Class c1 = d1.getClass();
  • 使用.class

さらに、以下を使用できます.class拡張子を使用してClassオブジェクトを生成。例えば、

Class c1 = Dog.class;

Classオブジェクトを生成した後、これらのオブジェクトを使用して反射を実行できます。

インターフェースの取得

ClassのgetInterfaces()メソッドを使用して、クラスが実装するインターフェースの情報を収集できます。このメソッドはインターフェースの配列を返します。

例:インターフェースの取得

import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
   public void display();
}
interface Mammal {
   public void makeSound();
}
class Dog implements Animal, Mammal {
   public void display() {
      System.out.println("I am a dog.");
   }
   public void makeSound() {
      System.out.println("吠え bark");
   }
}
class ReflectionDemo {
  public static void main(String[] args) {
      try {
          //Dogクラスのオブジェクトを作成
          Dog d1 = new Dog();
          //getClass()を使用してClassオブジェクトを作成
          Class obj = d1.getClass();
        
          //Dogが実装するインターフェースを検索
          Class[] objInterface = obj.getInterfaces();
          for(Class c : objInterface) {
              //インターフェース名を表示
              System.out.println("インターフェース名: ") + c.getName());
          }
      }
      catch(Exception e) {
          e.printStackTrace();
      }
   }
}

出力結果

インターフェース名: Animal
インターフェース名: Mammal

スーパークラスとアクセス修飾符の取得

クラスClassのメソッドgetSuperclass()は、特定のクラスのスーパークラスに関する情報を取得するために使用できます。

さらに、ClassはgetModifier()メソッドを提供しており、それはclassの修飾符を整数形式で返します。

例:スーパークラスとアクセス修飾符の取得

import java.lang.Class;
import java.lang.reflect.*;
interface Animal {
   public void display();
}
public class Dog implements Animal {
   public void display() {
       System.out.println("I am a dog.");
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
       try {
           //Dogクラスのオブジェクトを作成
           Dog d1 = new Dog();
           //getClass()を使用してClassオブジェクトを作成
           Class obj = d1.getClass();
           //Dogのアクセス修飾符を整数形式で取得
           int modifier = obj.getModifiers();
           System.out.println("修飾子: " + Modifier.toString(modifier));
           //Dogのスーパークラスを見つけます
           Class superClass = obj.getSuperclass();
           System.out.println("スーパークラス: " + superClass.getName());
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

出力結果

修飾子: public
スーパークラス: Animal

フィールド、メソッド、コンストラクタの反射

java.lang.reflectパッケージは、クラスメンバを実行するためのクラスを提供します。例えば、

  • メソッドクラス - クラス中のメソッドに関する情報を提供

  • フィールドクラス - クラス中のフィールドに関する情報を提供

  • コンストラクタクラス  - クラス中のコンストラクタに関する情報を提供

Java反射とフィールド

 Fieldクラスが提供するさまざまなメソッドを使用して、クラスの異なるフィールドをチェックおよび修正できます。

  • getFields() - クラスおよびそのスーパークラスのすべての公共フィールドを返す

  • getDeclaredFields()  - クラスのすべてのフィールドを返す

  • getModifier() - フィールドの修飾符を整数形式で返す

  • set(classObject,value) - 指定された値でフィールドの値を設定

  • get(classObject) - フィールドの値を取得

  • setAccessible(boolean) - 使私有字段可访问

注意:フィールド名がわかれば、使用できます

  • getField("fieldName") - クラスからfieldNameの公共フィールド。

  • getDeclaredField("fieldName") - クラスからfieldNameのフィールド。

例:公共フィールドへのアクセス

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
  public String type;
}
class ReflectionDemo {
  public static void main(String[] args) {
     try{
         Dog d1 = new Dog();
          //Classオブジェクトの作成
         Class obj = d1.getClass();
        //操纵Dog类的公共字段type
         Field field1 = obj.getField("type");
        //设置字段的值
         field1.set(d1, "labrador");
        //通过转换为字符串来获取字段的值
         String typeValue = (String)field1.get(d1);
         System.out.println("type: "); + typeValue);
         //获取类型的访问修饰符
         int mod1 = field1.getModifiers();
         String modifier1 = Modifier.toString(mod1);
         System.out.println("修飾子: " + modifier1);
         System.out.println(" ");
     }
     catch(Exception e) {
         e.printStackTrace();
     }
  }
}

出力結果

type: labrador
修飾子: public

示例:访问私有字段

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
 private String color;
}
class ReflectionDemo {
public static void main(String[] args) {
   try {
      Dog d1 = new Dog();
      //创建类Class对象
      Class obj = d1.getClass();
      //访问私有字段
      Field field2 = obj.getDeclaredField("color");
     
      //使私有字段可访问
      field2.setAccessible(true);
      //设置color值
      field2.set(d1, "brown");
      // 将类型转换为字符串以获取值
      String colorValue = (String)field2.get(d1);
      System.out.println("color: "); + colorValue);
      //获取color的访问修饰符
      int mod2 = field2.getModifiers();
      String modifier2 = Modifier.toString(mod2);
      System.out.println("modifier: "); + modifier2);
   }
   catch(Exception e) {
      e.printStackTrace();
   }
 }
}

出力結果

color: brown
modifier: private

Java 反射与方法

像字段一样,我们可以使用Method类提供的各种方法来检查类的不同方法。

  • getMethods() - 返回该类及其超类的所有公共方法

  • getDeclaredMethod() - 返回该类的所有方法

  • getName() - 返回方法的名称

  • getModifiers() - 以整数形式返回方法的访问修饰符

  • getReturnType() - 返回方法的返回类型

示例:方法反射

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
   public void display() {
      System.out.println("I am a dog.");
   }
   protected void eat() {
      System.out.println("I eat dog food.");
   }
   private void makeSound() {
      System.out.println("Bark Bark");
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
      try {
          Dog d1 = new Dog();
          //Classオブジェクトを生成します
          Class obj = d1.getClass();
          
          //getDeclaredMethod()を使用してすべてのメソッドを取得します
          Method[] methods = obj.getDeclaredMethods();
          //メソッドの名前を取得します
          for(Method m : methods) {
               
             System.out.println("メソッド名: "); + m.getName());
              
             //メソッドのアクセス修飾符を取得します
             int modifier = m.getModifiers();
             System.out.println("修飾子: " + Modifier.toString(modifier));
              
             //メソッドの返却型を取得します
             System.out.println("Return Types: "); + m.getReturnType());
             System.out.println(" ");
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
   }
}

出力結果

メソッド名: display
修飾子: public
Return type: void
メソッド名: eat
修飾符: protected
返却型: void
メソッド名: makeSound
修飾子: private
返却型: void

Javaの反射とコンストラクタ

また、Constructorクラスが提供するさまざまなメソッドを使用して、クラスの異なるコンストラクタをチェックすることができます。

  • getConstructors() - このクラスのすべてのパブリックコンストラクタおよびそのスーパークラスを返します

  • getDeclaredConstructor() -すべてのコンストラクタを返します

  • getName() - コンストラクタの名前を返します

  • getModifiers() - コンストラクタのアクセス修飾符を整数形式で返します

  • getParameterCount() - コンストラクタの引数の数を返します

例:コンストラクタの反射

import java.lang.Class;
import java.lang.reflect.*;
class Dog {
   public Dog() {
      
   }
   public Dog(int age) {
      
   }
   private Dog(String sound, String type) {
      
   }
}
class ReflectionDemo {
   public static void main(String[] args) {
      try {
           Dog d1 = new Dog();
           Class obj = d1.getClass();
           //getDeclaredConstructor()を使用してクラス内のすべてのコンストラクタを取得します
           Constructor[] constructors = obj.getDeclaredConstructors();
           for(Constructor c : constructors) {
               //コンストラクタの名前を取得
               System.out.println("コンストラクタ名: " + c.getName());
               //コンストラクタのアクセス修飾子を取得
               int modifier = c.getModifiers();
               System.out.println("修飾子: " + Modifier.toString(modifier));
               //コンストラクタの引数の数を取得
               System.out.println("引数の数: " + c.getParameterCount());
          }
       }
       catch(Exception e) {
           e.printStackTrace();
       }
    }
}

出力結果

コンストラクタ名: Dog
修飾子: public
引数の数: 0
コンストラクタ名: Dog
修飾子: public
引数の数: 1
コンストラクタ名: Dog
修飾子: private
引数の数: 2