目次 | 前の項目 | 次の項目Java Core Reflection


概要

JavaTM Core Reflection API は、現在動作中の Java 仮想マシン* 内のクラスやオブジェクトに関するイントロスペクションをサポートする、小規模で、型が保証された API を提供します。セキュリティポリシーで認められる場合、API を使って次のことを実行できます。

Core Reflection API が定義するクラスおよびメソッドは、次のとおりです。

リフレクションをサポートする java.lang パッケージにも、次のようなものがあります。

アプリケーション

Core Reflection API を使うと、次のような 2 種類のアプリケーションを作成できるようになります。

1 つは、実行時のクラスに基づくターゲットオブジェクトの、すべての public メンバを見つけ出して使う必要があるアプリケーションの集合です。これらのアプリケーションは、オブジェクトのすべての public フィールド、メソッド、およびコンストラクタに実行時にアクセスする必要があります。このカテゴリに入るアプリケーションには、JavaTM Beans[1]、あるいはオブジェクトインスペクタなどの簡易ツールがあります。これらのアプリケーションは、クラス Class のメソッド getFieldgetMethodgetConstructorgetFieldsgetMethods、および getConstructorsから取得したクラス FieldMethod、および Constructor のインスタンスを使います。

もう 1 つは、特定のクラスが宣言したメンバを見つけ出して使う必要のある、複雑なアプリケーションの集合です。これらのアプリケーションは、class ファイルが指定したレベルのクラス実装への実行時アクセスが必要です。このカテゴリに入るアプリケーションには、インタプリタ、インスペクタ、クラスブラウザなどの開発ツールや、JavaTM オブジェクト直列化 [2] などの実行サービスがあります。これらのアプリケーションは、クラス Class のメソッド getDeclaredFieldgetDeclaredMethodgetDeclaredConstructorgetDeclaredFieldsgetDeclaredMethods、および getDeclaredConstructors から取得したクラス FieldMethod、および Constructor のインスタンスを使います。


リフレクションモデル

3 つのクラス FieldMethod、および Constructorfinal です。これらのクラスのインスタンスを生成できるのは、Java 仮想マシンだけです。 これらのオブジェクトを使って基本オブジェクトを操作します。

インスタンスを生成できない final クラス Array には、新規配列の作成、配列要素の取得と設定を行えるようにする static メソッドが備わっています。

Member インタフェース

クラス FieldMethod および Constructor は、Member インタフェースを実装します。クラス Member のメソッドを使って、基本の識別情報をリフレクトされたメンバを問い合わせます。識別情報には、メンバを宣言したクラスまたはインタフェース、メンバ名、およびメンバの Java 言語修飾子 (publicprotectedabstractsynchronized など) が含まれます。

Field オブジェクト

Field オブジェクトは、基本フィールドを反映したフィールドを表します。基本フィールドはクラス変数 (static フィールド) でもインスタンス変数 (非 static フィールド) でも構いません。クラス Field のメソッドを使って、基本フィールドの型を獲得し、オブジェクトの基本フィールド値を取得して設定します。

Method オブジェクト

Method オブジェクトは、基本フィールドを反映したメソッドを表します。基本メソッドは、abstract メソッド、インスタンスメソッド、クラス (static) メソッドのどれでも構いません。

クラス Method のメソッドを使って、基本メソッドの仮パラメータの型、戻り値の型、および確認済み例外の型を取得します。また、クラス Methodinvoke メソッドを使って、ターゲットオブジェクトの基本メソッドを呼び出します。インスタンスおよび abstract メソッドの呼び出しでは、ターゲットオブジェクトの実行クラスおよびリフレクトされたメソッドの宣言クラス、名前、および仮パラメータの型に基づいた動的なメソッドの解決を使います。このため、インタフェースを実装するクラスのインスタンスであるオブジェクトについて、リフレクトされたインタフェースメソッドを呼び出すことができます。メソッド呼び出しでは、メソッドの宣言クラスの基本 static メソッドを使います。

Constructor オブジェクト

Constructor オブジェクトは、リフレクトされたコンストラクタを表します。クラス Constructor のメソッドを使って、基本コンストラクタの仮パラメータ型と確認済みの例外の型を取得します。さらに、クラスがインスタンスを実行できる場合は、クラス ConstructornewInstance メソッドを使って、コンストラクタを宣言するクラスの新規インスタンスを生成して初期化します。

Array および Modifier クラス

Array クラスはインスタンスを生成できないクラスです。 クラスメソッドをエクスポートして、プリミティブ型またはクラス型コンポーネントを持つ Java 配列を生成します。クラス Array のメソッドを使って、配列を構成する値の取得と設定も行います。

Modifier クラスはインスタンスを生成できないクラスです。 クラスメソッドをエクスポートして、クラスやメンバの Java 言語修飾子を復号化します。言語修飾子は、Java 仮想マシン仕様で定義されたコード化定数を使って整数型に符号化します。

プリミティブ Java 型の表現

Class オブジェクトが 9 つあります。 これらのオブジェクトを使って、8 つのプリミティブ Java 型と void を実行時に表現します。(これらは Class オブジェクトであって、クラスではないことに注意してください。)Core Reflection API はこれらの Class オブジェクトを使って、次のものを識別します。

Java 仮想マシンは、これらの 9 つの Class オブジェクトを生成します。これらのオブジェクト名は、それぞれが表す型と同じです。Class オブジェクトは、次の public final static 変数を介してだけ参照できます。

    

        java.lang.Boolean.TYPE

        java.lang.Character.TYPE

        java.lang.Byte.TYPE

        java.lang.Short.TYPE

        java.lang.Integer.TYPE

        java.lang.Long.TYPE

        java.lang.Float.TYPE

        java.lang.Double.TYPE

        java.lang.Void.TYPE

特に、これらの Class オブジェクトは、クラス ClassforName メソッドからはアクセスできません。


セキュリティモデル

Java セキュリティマネージャは、クラス単位で Core Reflection API へのアクセスを制御します。セキュリティを施行するには、次の 2 つのレベルを確認する必要があります。

ポリシーの決定は、クラス SecurityManager の 2 つのメソッドで行います。

void checkMemberAccess(Class,int) throws SecurityException

checkMemberAccess の第 1 パラメータは、アクセスが必要なメンバを持つクラスやインタフェースを指定します。第 2 パラメータはアクセスされるメンバセット (Member.PUBLIC または Member.DECLARED のいずれか) を指定します。

void checkPackageAccess(String pkg) throws SecurityException

ポリシーは、呼び出し側にどのようなアクセス権が付与されているかによって決定されます。これらのポリシーに影響を与えるクラス java.lang.RuntimePermission の 2 つのアクションを次に挙げます。

指定クラスの指定メンバセットへのアクセス要求が拒否されると、メソッドは SecurityException をスローします。セットへのアクセスが付与されると、メソッドは復帰します。

前述したように、このセットのリフレクトされたメンバを使って以下のような基本オブジェクトの操作を行うときは、通常、標準の Java 言語アクセス制御が実行されます。

この時点でアクセスが拒否されると、リフレクトされたメンバは IllegalAccessException をスローします。特定のリフレクトされたメンバへの Java 言語アクセス制御は、setAccessible メソッドを使ってフラグを設定することにより抑制できます。 たとえば、次のとおりです。

Java Language Policy

アプリケーションに関する Java 言語セキュリティポリシーは、任意のコードが、リンクする先の任意のクラスのすべてのメンバおよびコンストラクタ (public でないメンバとコンストラクタを含む) への反映的なアクセスを取得できるということです。デフォルトでは、メンバまたはコンストラクタへの反映的なアクセスを取得するアプリケーションコードは、標準の Java 言語アクセス制御とともにリフレクトされたメンバまたはコンストラクタを使うことだけができます。

標準ポリシーは、リフレクトされたメンバの setAccessible メソッドを呼び出すとオーバーライドされます。そして、setAccessible メソッドの呼び出しは、アクセス権 ReflectPermissionsuppressAccessChecks ターゲットによって制御されます。


データ変換

リフレクションパッケージの特定メソッドは、プリミティブ型とクラス型オブジェクト間のデータ変換を自動的に実行します。フィールドおよび配列のコンポーネント値を取得したり、設定したりするための汎用メソッド、およびメソッドとコンストラクタ呼び出しのためのメソッドがあります。

自動データ変換には次の 2 つのタイプがあります。「ラッピング変換」は、プリミティブ型からクラス型オブジェクトの値に変換します。「アンラッピング変換」は、クラス型オブジェクトからプリミティブ型の値に変換します。これらの変換に関する規則は、「ラッピング変換とアンラッピング変換」で定義します。

さらに、フィールドアクセスとメソッド呼び出しは、プリミティブ型および参照型について「拡張変換」を可能にします。これらの変換については、Java 言語仕様の項 5 を参照してください。 より詳細な情報は、「拡張変換」を参照してください。

ラッピング変換とアンラッピング変換

プリミティブ値は、Field.get または Array.get で取得したり、Method.invoke から呼び出したメソッドによって返されると、自動的にオブジェクトにラップされます。

同様にオブジェクト値は、プリミティブ型の値を必要とする、以下のコンテキストのパラメータとして提供されると、自動的にアンラップされます。

以下は、プリミティブ型とクラス (ラッパー) 型の対応表です。

プリミティブ型 クラス型
boolean java.lang.Boolean
char java.lang.Character
byte java.lang.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double

void 宣言されるメソッドは、Method.invoke から呼び出されると、null を返します。

拡張変換

リフレクションパッケージでは、コンパイル時にメソッド呼び出しコンテキストで認められるものと同じ拡張変換が可能です。これらの変換は、Java 言語仕様の項 5.3 で定義されます。

拡張変換は、以下の実行時に行われます。

認められる拡張プリミティブ変換には、次のものがあります。

認められる拡張参照変換には次のものがあります。


パッケージ

Core Reflection API は、java.langjava.lang.reflect という名前のサブパッケージにあります。 Java の既定パッケージのインポート規則に触れて互換性の問題が発生することはありません。

* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。


目次 | 前の項目 | 次の項目
Copyright © 1996, 1997, 1998 Sun Microsystems, Inc. All rights reserved.