| 目次 | 前の項目 | 次の項目 | Java Core Reflection |
Core Reflection API が定義するクラスおよびメソッドは、次のとおりです。
Field、Method、および Constructor - これらは、クラスとインタフェースのメンバ、およびコンストラクタ自身を反映する。これらのクラスは、以下のものを提供する Field、Method、および Constructor クラスの新規インスタンスを構築する、クラス Class のメソッド Array - Java 配列を動的に生成し、その配列にアクセスするメソッドを提供する Modifier - クラスおよびそのメンバに関する Java 言語修飾子情報の復号化に役立つ InvocationTargetException - リフレクトされたメソッドまたはコンストラクタがスローした例外のラップに使用する AccessibleObject および ReflectPermission - 標準の Java 言語のアクセス制御を抑制する機構を提供する java.lang パッケージにも、次のようなものがあります。
Class のインスタンスを持つ static フィールド。これらは、実行時に、プリミティブ Java 型の boolean、byte、char、short、int、long、float、double、およびキーワード void を表す Void - キーワード void を表す Class オブジェクトを表す参照が入る 1 つは、実行時のクラスに基づくターゲットオブジェクトの、すべての public メンバを見つけ出して使う必要があるアプリケーションの集合です。これらのアプリケーションは、オブジェクトのすべての public フィールド、メソッド、およびコンストラクタに実行時にアクセスする必要があります。このカテゴリに入るアプリケーションには、JavaTM Beans[1]、あるいはオブジェクトインスペクタなどの簡易ツールがあります。これらのアプリケーションは、クラス Class のメソッド getField、getMethod、getConstructor、getFields、getMethods、および getConstructorsから取得したクラス Field、Method、および Constructor のインスタンスを使います。
もう 1 つは、特定のクラスが宣言したメンバを見つけ出して使う必要のある、複雑なアプリケーションの集合です。これらのアプリケーションは、class ファイルが指定したレベルのクラス実装への実行時アクセスが必要です。このカテゴリに入るアプリケーションには、インタプリタ、インスペクタ、クラスブラウザなどの開発ツールや、JavaTM オブジェクト直列化 [2] などの実行サービスがあります。これらのアプリケーションは、クラス Class のメソッド getDeclaredField、getDeclaredMethod、getDeclaredConstructor、getDeclaredFields、getDeclaredMethods、および getDeclaredConstructors から取得したクラス Field、Method、および Constructor のインスタンスを使います。
Field、Method、および Constructor は final です。これらのクラスのインスタンスを生成できるのは、Java 仮想マシンだけです。 これらのオブジェクトを使って基本オブジェクトを操作します。
インスタンスを生成できない
final クラス Array には、新規配列の作成、配列要素の取得と設定を行えるようにする static メソッドが備わっています。
Field、Method および Constructor は、Member インタフェースを実装します。クラス Member のメソッドを使って、基本の識別情報をリフレクトされたメンバを問い合わせます。識別情報には、メンバを宣言したクラスまたはインタフェース、メンバ名、およびメンバの Java 言語修飾子 (public、protected、abstract、synchronized など) が含まれます。
Field オブジェクトは、基本フィールドを反映したフィールドを表します。基本フィールドはクラス変数 (static フィールド) でもインスタンス変数 (非 static フィールド) でも構いません。クラス Field のメソッドを使って、基本フィールドの型を獲得し、オブジェクトの基本フィールド値を取得して設定します。
Method オブジェクトは、基本フィールドを反映したメソッドを表します。基本メソッドは、abstract メソッド、インスタンスメソッド、クラス (static) メソッドのどれでも構いません。
クラス Method のメソッドを使って、基本メソッドの仮パラメータの型、戻り値の型、および確認済み例外の型を取得します。また、クラス Method の invoke メソッドを使って、ターゲットオブジェクトの基本メソッドを呼び出します。インスタンスおよび abstract メソッドの呼び出しでは、ターゲットオブジェクトの実行クラスおよびリフレクトされたメソッドの宣言クラス、名前、および仮パラメータの型に基づいた動的なメソッドの解決を使います。このため、インタフェースを実装するクラスのインスタンスであるオブジェクトについて、リフレクトされたインタフェースメソッドを呼び出すことができます。メソッド呼び出しでは、メソッドの宣言クラスの基本 static メソッドを使います。
Constructor オブジェクトは、リフレクトされたコンストラクタを表します。クラス Constructor のメソッドを使って、基本コンストラクタの仮パラメータ型と確認済みの例外の型を取得します。さらに、クラスがインスタンスを実行できる場合は、クラス Constructor の newInstance メソッドを使って、コンストラクタを宣言するクラスの新規インスタンスを生成して初期化します。
Array クラスはインスタンスを生成できないクラスです。 クラスメソッドをエクスポートして、プリミティブ型またはクラス型コンポーネントを持つ Java 配列を生成します。クラス Array のメソッドを使って、配列を構成する値の取得と設定も行います。
Modifier クラスはインスタンスを生成できないクラスです。 クラスメソッドをエクスポートして、クラスやメンバの 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 オブジェクトは、クラス Class の forName メソッドからはアクセスできません。
Class のメソッドが Field、Method、および Constructor のインスタンスのソースだけであること。これらのメソッドは最初に、システムセキュリティマネージャ (インストールされている場合) にセキュリティチェックを渡す。 セキュリティマネージャは、リフレクティブなアクセス要求が拒否された場合に、SecurityException をスローする protected、デフォルトの (パッケージ) アクセス、および private クラスとメンバについては、個々のリフレクトされたメンバを使ってオブジェクトの基本メンバを操作する (つまり、フィールド値の取得や設定、メソッドの呼び出し、新規オブジェクトの生成と初期化を行う) ときに、標準の Java 言語アクセス制御チェックが実行される。特権コードには、setAccessible メソッドを使って、無制限アクセス (標準の言語アクセス制御規則をオーバーライドするもの) を付与することができる。このメソッドは、クラス Field、Method、および Constructor によって、AccessibleObject から継承される 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 つのアクションを次に挙げます。
accessDeclaredMembers - クラスの public でないメンバへのリフレクトを許可する accessClassInPackage{package name} - 指定したパッケージのクラスへのアクセスを許可する。これらのアクセス権はセキュリティマネージャによって決定される SecurityException をスローします。セットへのアクセスが付与されると、メソッドは復帰します。
前述したように、このセットのリフレクトされたメンバを使って以下のような基本オブジェクトの操作を行うときは、通常、標準の Java 言語アクセス制御が実行されます。
この時点でアクセスが拒否されると、リフレクトされたメンバは
IllegalAccessException をスローします。特定のリフレクトされたメンバへの Java 言語アクセス制御は、setAccessible メソッドを使ってフラグを設定することにより抑制できます。 たとえば、次のとおりです。
public でないメンバとコンストラクタを含む) への反映的なアクセスを取得できるということです。デフォルトでは、メンバまたはコンストラクタへの反映的なアクセスを取得するアプリケーションコードは、標準の Java 言語アクセス制御とともにリフレクトされたメンバまたはコンストラクタを使うことだけができます。
標準ポリシーは、リフレクトされたメンバの setAccessible メソッドを呼び出すとオーバーライドされます。そして、setAccessible メソッドの呼び出しは、アクセス権 ReflectPermission の suppressAccessChecks ターゲットによって制御されます。
自動データ変換には次の 2 つのタイプがあります。「ラッピング変換」は、プリミティブ型からクラス型オブジェクトの値に変換します。「アンラッピング変換」は、クラス型オブジェクトからプリミティブ型の値に変換します。これらの変換に関する規則は、「ラッピング変換とアンラッピング変換」で定義します。
さらに、フィールドアクセスとメソッド呼び出しは、プリミティブ型および参照型について「拡張変換」を可能にします。これらの変換については、Java 言語仕様の項 5 を参照してください。 より詳細な情報は、「拡張変換」を参照してください。
Field.get または Array.get で取得したり、Method.invoke から呼び出したメソッドによって返されると、自動的にオブジェクトにラップされます。
同様にオブジェクト値は、プリミティブ型の値を必要とする、以下のコンテキストのパラメータとして提供されると、自動的にアンラップされます。
Field.set の場合、基本フィールドはプリミティブ型を持つ Array.set の場合、基本配列はプリミティブ要素型を持つ Method.invoke または Constructor.newInstance の場合、基本メソッドまたはコンストラクタに対応する仮パラメータはプリミティブ型を持つ
| プリミティブ型 | クラス型 |
|---|---|
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 を返します。
Field および Array のメソッドを介して、フィールドまたは配列から値を取得するときField および ArrayMethod.invoke または Constructor.newInstance を介するメソッドあるいはコンストラクタの呼び出し中に、アンラップの実パラメータ値を対応する仮パラメータに変換するとき
byte から short、int、long、float、または double への変換short から int、long、float、または double への変換char から int、long、float、または double への変換int から long、float、または double への変換long から float または double への変換float から double への変換
java.lang の java.lang.reflect という名前のサブパッケージにあります。 Java の既定パッケージのインポート規則に触れて互換性の問題が発生することはありません。
* この Web サイトで使用されている用語「Java 仮想マシン」または「JVM」は、Java プラットフォーム用の仮想マシンを表します。