目次 | 前へ | 次へ Java Core Reflection


概要

Java(TM) Core Reflection API は、現在の Java 仮想マシン* 内のクラスやオブジェクトに関するイントロスペクションをサポートする、小さな、型保証された、安全な API を提供します。セキュリティーポリシーで許可される場合、API を使って次のことを実行できます。 Core Reflection API は次のようにクラスおよびメソッドを定義します。 java.lang パッケージにもリフレクションをサポートするものがあります。次に初期参照を示します。

アプリケーション

Core Reflection API は、2 つのカテゴリのアプリケーションに対応します。

1 つのカテゴリは、実行時クラスに基づいてターゲットオブジェクトのすべての public メンバーを検出して使用する必要があるアプリケーションで構成されます。これらのアプリケーションには、オブジェクトのすべての public フィールド、メソッド、およびコンストラクタへの実行時アクセスが必要です。このカテゴリの例は、Java(TM) Beans[1] などのサービス、オブジェクトインスペクタなどの軽量ツールです。これらのアプリケーションは、クラス Class のメソッド getFieldgetMethodgetConstructorgetFieldsgetMethods、および getConstructors によって取得されたクラス FieldMethod、および Constructor のインスタンスを使用します。

もう 1 つのカテゴリは、指定されたクラスによって宣言されたメンバーを検出して使用する必要がある、高度なアプリケーションで構成されます。これらのアプリケーションには、class ファイルによって指定されたレベルのクラスの実装への、実行時アクセスが必要です。このカテゴリに入るアプリケーションには、インタプリタ、インスペクタ、クラスブラウザなどの開発ツールや、Java(TM) オブジェクト直列化 [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 メソッド呼び出しは、メソッドの宣言クラスの基になる static メソッドを使用します。

Constructor オブジェクト

Constructor オブジェクトは、リフレクションされるコンストラクタを表します。クラス Constructor のメソッドは、基になるコンストラクタの仮パラメータ型とチェック例外型を取得するために使用されます。さらに、クラス ConstructornewInstance メソッドは、コンストラクタを宣言するクラスの新規インスタンスを作成して初期化するために使用されます (クラスがインスタンス化可能である場合)。

Array および Modifier クラス

Array クラスは、プリミティブまたはクラスコンポーネント型の Java 配列を作成するクラスメソッドをエクスポートする、インスタンス化できないクラスです。クラス Array のメソッドは、配列コンポーネント値を取得/設定するためにも使用されます。

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

プリミティブ Java 型の表現

最後に、8 個のプリミティブ Java 型と void を実行時に表現するために使用される、9 個の Class オブジェクトがあります。(これらは Class オブジェクトで、クラスではありません。) Core Reflection API はこれらのオブジェクトを使って次のものを識別します。 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

checkMemberAccessClass パラメータは、メンバーへのアクセスが必要なクラスやインタフェースを識別します。int パラメータは、アクセスされるメンバーセット (Member.PUBLIC または Member.DECLARED のいずれか) を識別します。

void checkPackageAccess(String pkg) throws SecurityException

ポリシーは、呼び出し側にどのようなアクセス権が付与されているかによって決定されます。これらのポリシーに影響を与えるクラス java.lang.RuntimePermission の 2 つのアクションを次に挙げます。次に初期参照を示します。 指定されたクラスの指定されたメンバーセットへの要求されたアクセスが拒否された場合、メソッドは SecurityException をスローします。セットへの要求されたアクセスが付与されると、メソッドは復帰します。

前述したように、このセットからリフレクションされるメンバーが次のような基になるオブジェクトでの操作に使用されるときは通常、Java 言語標準アクセス制御が適用されます。

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

Java 言語ポリシー

アプリケーション用の 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 Oracle Corp. All rights reserved.

Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.