| 目次 | 前項目 | 次項目 | Java コアリフレクション |
コアリフレクション API が定義する新規クラスおよびメソッドは、次のとおりです:
Field, Method, および Constructor - これらは、クラスとインタフェースのメンバ、および構築子を反射する。これらのクラスは、以下のものを提供する: Field, Method, および Constructor クラスの新規インスタンスを構築する、クラス Class の新規メソッドArray - これは、Java 配列をダイナミックに構築/アクセスするメソッドを提供する。Modifier - これは、クラスおよびそのメンバに関する Java 言語修飾子情報の解読に役立つ。java.lang パッケージにも、次の内容が追加されました:
Byte と Short。この新規クラスはクラス Number のサブクラスで、クラス Integer に類似している。これらの新規クラスのインスタンスは、型 byte および short のプリミティブ値用オブジェクトラッパとして、それぞれに機能する。boolean, byte, char, short, int, long, float, double およびキーワード void を表す新規オブジェクト、クラス Class のインスタンス。Void - これには、キーワード void を表す Class オブジェクトを表す参照が入る。
1 つは、実行クラスに基づくターゲットオブジェクトの、すべての public メンバを見つけ出して使う必要があるアプリケーションの集合です。これらのアプリケーションは、オブジェクトのすべての public フィールド、メソッド、および構築子に実行時にアクセスする必要があります。このカテゴリに入るアプリケーションには、Java(TM) Beans[1]、あるいはオブジェクトインスペクタなどの簡易ツールがあります。これらのアプリケーションは、クラス Class のメソッド getField, getMethod, getConstructor, getFields, getMethods, および getConstructors から獲得したクラス Field, Method, および Constructor のインスタンスを使います。
もう 1 つは、所定クラスが宣言したメンバを見つけ出して使う必要のある、複雑なアプリケーションの集合です。これらのアプリケーションは、class ファイルが指定したレベルのクラス実装への実行時アクセスが必要です。このカテゴリに入るアプリケーションには、デバッガ、インタプリタ、インスペクタ、クラスブラウザなどの開発ツールや、Java(TM) オブジェクト直列化[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 オブジェクトであって、クラスではないことに注意してください。)コアリフレクション 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 言語アクセス制御チェックが実行される。デバッガコードなどの特権コードには、無制限アクセス (標準の言語アクセス制御規則をオーバーライドするもの) を付与することができる。この仕様の今後のバージョンでは、インタフェースを定義することにより、無制限アクセスを実行できるようになる。SecurityManager の新規メソッドである checkMemberAccess メソッドで行います。第 1 パラメータは、アクセスが必要なメンバを持つクラスやインタフェースを指定します。第 2 パラメータはアクセスされるメンバセット (void checkMemberAccess(Class,int) throws SecurityException
Member.PUBLIC または Member.DECLARED のいずれか) を指定します。
指定クラスの指定メンバセットへのアクセス要求が拒否されると、メソッドは SecurityException をスローします。セットへのアクセスが付与されると、メソッドは返ります。
既に説明したように、このセットの反射されたメンバを使って以下のような基本オブジェクトの操作を行うときは、標準の Java 言語アクセス制御が実行されます:
この時点でアクセスが拒否されると、反射されたメンバは
IllegalAccessException をスローします。public メンバと構築子を含む) への反射的アクセスを獲得できるということです。メンバまたは構築子への反射的アクセスを獲得するアプリケーションコードが反射された再帰メンバまたは構築子を使うことができるのは、標準の Java 言語アクセス制御がある場合だけです。AppletSecurity が以下のポリシーを実装します:
public クラスのすべての public メンバpublic システムクラスのすべての public メンバpublic を含む)CLASSPATH からロードされたコード - には、すべてのクラスローダがロードした全クラスへのアクセスが認められる。
このポリシーは、安全性が保障されないコードに関しては厳密で、Java 仮想マシンのリンカよりも厳しく限定されます。例えば、安全性が保障されないクラスだけでは、リフレクション経由でシステムスーパークラスの protected メンバにアクセスできません。これに対して、リンカ経由ではアクセス可能です。(ただし、システムコードがこのようなメンバにアクセスして、メンバを信頼されないコードに渡すことはできます)。
JDK のセキュリティポリシーは、今後 Java のセキュリティフレームワークに発展していくと期待されています。
自動データ変換には次の 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 および Array のメソッドを介して、フィールドまたは配列に値を格納するときMethod.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 の既定パッケージのインポート規則に触れて互換性の問題が発生することはありません。