Java™ アクセス関数 は、EGL システム関数です。これによって、 ユーザーが作成した Java コードで、ネイティブ Java オブジェクトおよびクラス (特にネイティブ・コードの public メソッド、コンストラクター、およびフィールド) にアクセスできます。
EGL フィーチャーは、実行時に EGL Java オブジェクト・スペース が存在する場合に使用可能になります。EGL Java ネームスペースは、一連の名前とそれらの名前 が参照するオブジェクトです。 生成したプログラムとそれらのプ ログラムがローカルで呼び出すすべての生成済み Java コードで、単一のオブジェクト・スペースを使用できます。呼 び出しが直接呼び出しであるか別のローカル生成された Java プログラムを介して いるかにかかわらず、任意のレベルの呼び出しで使用できます。オブジェクト・スペースは任意のネイティブ Java コ ードで使用できるわけではありません。
オブジェクトをネームスペースに格納したりオブジェクト・スペースで検索したりする には、Java アクセス関数を呼び出します。呼び出しでは ID も使用します。各 ID は、オ ブジェクトをオブジェクト・スペースに格納したり、すでに存在する名前と一致させるために使用 されるストリングです。ID が名前と一致すると、コードからその名前に関連付けられ たオブジェクトにアクセスできます。
メソッドに渡すそれぞれの引き数 (およびフィールドに割り当てるそれぞれの値) は、Java オブジェクトまたはプリミティブ型へマップされます。 例えば、EGL プリミティブ型 CHAR の項目は、Java String クラスのオブジェクトとして渡されます。 EGL の型から Java の型へのマッピングが不十分な場合のために、キャスト演算子が提供されています。
Java 名を指定すると、EGL は、値の先頭と最後から、単一バイトのブランクと 2 バイトのブランクを削除します。この値では、大/小文字が区別されます。 切り捨ては、どのキャストよりも先に行われます。この規則は、ストリング・リテラル、および CHAR 型、DBCHAR 型、MBCHAR 型、または UNICODE 型の項目に適用されます。値を objID または null にキャストしない限り、メソッド引き数またはフィールド値の指定時に、このような切り捨ては行われません (例えば、ストリング "my data" は、そのままの形でメソッドに渡されます)。
次の表は、有効なマッピングをすべてまとめたものです。
引き数のカテゴリー | 例 | Java の型 | |
---|---|---|---|
ストリング・リテラル、または CHAR 型、DBCHAR 型、MBCHAR 型、UNICODE 型の項目 | キャストなし | "myString" |
java.lang.String |
ID を示す objId でキャスト | (objId)"myId" x = "myId"; (objId)X |
ID が参照するオブジェクトのクラス | |
null でキャスト。これは、完全修飾クラスに null 参照を提供するのに適しています | (null)"java. lang.Thread" x = "java.util. HashMap"; (null)x |
指定したクラス
注: (null)"int[]" などの null でキャストされた配列に渡すことはできません
|
|
char でキャスト。これは、値の先頭の文字が渡されることを意味します (次の列の例ではそれぞれ "a" が渡されます) | (char)"abc" X = "abc"; (char)X |
char | |
FLOAT 型の項目または浮動小数点数リテラル | キャストなし | myFloatValue |
double |
HEX 型の項目 | キャストなし | myHexValue |
バイト配列 |
SMALLFLOAT 型の項目 | キャストなし | mySmallFloat |
float |
DATE 型の項目 | キャストなし | myDate |
java.sql.Date |
TIME 型の項目 | キャストなし | myTime |
java.sql.Time |
TIMESTAMP 型の項目 | キャストなし | myTimeStamp |
java.sql.Timestamp |
INTERVAL 型の項目 | キャストなし | myInterval |
java.lang.String |
浮動小数点数リテラル | キャストなし | -6.5231E96 | double |
小数部を含まない数値項目 (または非浮動小数点数リテラル)。先行ゼロは、リテラルの桁数に含まれます。 | キャストなし、1 - 4 桁 | 0100 |
short |
キャストなし、5 から 9 桁 | 00100 |
int | |
キャストなし、9 から 18 桁 | 1234567890 |
long | |
キャストなし、18 桁より大 | 1234567890123456789 |
java.math.BigInteger | |
小数部を含む数値項目 (または非浮動小数点数リテラル)。先行ゼロおよび後続ゼロは、リテラルの桁数に含まれます。 | キャストなし、1 から 6 桁 | 3.14159 |
float |
キャストなし、7 から 18 桁 | 3.14159265 |
double | |
キャストなし、18 桁より大 | 56789543.222 |
java.math.BigDecimal | |
小数部付き、または小数部なしの数値項目または非浮動小数点数リテラル | bigdecimal、biginteger、byte、double、float、short、int、long でキャスト | X = 42; (byte)X (long)X |
指定した基本型。ただし、値がその型の範囲を超えると、精度が失われ、符号が変わることがあります。 |
ブール値へのキャスト。これは、ゼロ以外が真、ゼロが偽であることを意味します。 | X = 1; (boolean)X |
boolean |
EGL 内の項目の内部形式については、『基本型』のページを参照してください。
このセクションでは、Java アクセス関数の使用方法について例を示します。
// Java Date クラスのコンストラクターを呼び出し // 新規オブジェクトを ID "date" に割り当てます。 JavaLib.storeNew( (objId)"date", "java.util.Date" ); // 新規 Date オブジェクトの toString メソッドを呼び出し // 出力 (本日の日付) を chaItem に割り当てます。 // キャスト (objId) が存在しない場合、"date" は // オブジェクトではなくクラスを参照します。 charItem = JavaLib.invoke( (objId)"date", "toString" ); // Java System クラスの標準出力ストリームを // ID "systemOut" に割り当てます。 JavaLib.storeField( (objId)"systemOut", "java.lang.System", "out" ); // 出力ストリームの println メソッドを呼び出し // 今日の日付を出力します。 JavaLib.invoke( (objID)"systemOut","println",charItem ); // "java.lang.System.out" を // 前の行の第 1 引き数として使用すると、 // 無効です。この引き数は、すでにオブジェクト・スペース内にある // 識別子であるか、クラス名であることが必要だからです。 // この引き数は static フィールドを参照できません。
// ID の名前を CHAR 型の項目に割り当てます valueID = "osNameProperty" // プロパティー os.name の値を // オブジェクト・スペースに格納し、この値 (Java の String) を ID osNameProperty に // 関連付けます JavaLib.store((objId)valueId, "java.lang.System", "getProperty", "os.name"); // プロパティー値が存在しないかどうかをテストし、 // それに応じて処理を実行します myNullFlag = JavaLib.isNull( (objId)valueId ); if( myNullFlag == 1 ) error = 27; end
EGL で Java 配列を扱うときは、Java クラス java.lang.reflect.Array を使用します (詳細については、以降の例や Java API 文書を参照してください)。 Java 配列はコンストラクターを持たないため、JavaLib.storeNew を使用して Java 配列を作成することはできません。
オブジェクト・スペースに配列を作成するには、java.lang.reflect.Array の静的メソッド newInstance を使用します。 配列を作成したら、そのクラスの他のメソッドを使用して、エレメントにアクセスします。
Class オブジェクトを識別するコードは、オブジェクト配列、または基本配列のどちらを作成するのかに応じて変化します。配列と対話する後続のコードも、これと同じ基準で変化します。
// newInstance で使用するためにクラスへの参照を取得します JavaLib.store( (objId)"objectClass", "java.lang.Class", "forName", "java.lang.Object" ); // オブジェクト・スペース内に配列を作成します JavaLib.store( (objId)"myArray", "java.lang.reflect.Array", "newInstance", (objId)"objectClass", 5 );
異なる型のオブジェクトを保持する配列を作成したい場合は、JavaLib.store の最初の呼び出しに渡すクラス名を変更してください。 String オブジェクトの配列を作成するには、例えば、"java.lang.Object" の代わりに "java.lang.String" を渡します。
length = JavaLib.invoke( "java.lang.reflect.Array", "getLength", (objId)"myArray" ); i = 0; while ( i < length ) JavaLib.store( (objId)"element", "java.lang.reflect.Array", "get", (objId)"myArray", i ); // ここで、エレメントを適宜処理します JavaLib.invoke( "java.lang.reflect.Array", "set", (objId)"myArray", i, (objId)"element" ); i = i + 1; end
int length = myArray.length; for ( int i = 0; i < length; i++ ) { Object element = myArray[i]; // ここで、エレメントを適宜処理します myArray[i] = element; }
オブジェクトではなく、Java プリミティブを格納する配列を作成するには、java.lang.reflect.Array を使用するより前のステップで、別のメカニズムを使用します。 特に、基本型クラスの静的フィールド TYPE にアクセスして、newInstance の Class 引き数を取得する必要があります。
// newInstance で使用するためにクラスへの参照を取得します JavaLib.storeField( (objId)"intClass", "java.lang.Integer", "TYPE"); // オブジェクト・スペース内に配列を作成します JavaLib.store( (objId)"myArray2", "java.lang.reflect.Array", "newInstance", (objId)"intClass", 30 );
異なる型のプリミティブを保持する配列を作成したい場合は、JavaLib.storeField の呼び出しに渡すクラス名を変更してください。 文字配列を作成するには、例えば、"java.lang.Integer" の代わりに "java.lang.Character" を渡します。
length = JavaLib.invoke( "java.lang.reflect.Array", "getLength", (objId)"myArray2" ); i = 0; while ( i < length ) element = JavaLib.invoke( "java.lang.reflect.Array", "getDouble", (objId)"myArray2", i ); // ここで、エレメントを適宜処理します JavaLib.invoke( "java.lang.reflect.Array", "setDouble", (objId)"myArray2", i, element ); i = i + 1; end
int length = myArray2.length; for ( int i = 0; i < length; i++ ) { double element = myArray2[i]; // ここで、エレメントを適宜処理します myArray2[i] = element; }
Iterator contents = list.iterator(); while( contents.hasNext() ) { Object myObject = contents.next(); // myObject を処理します }
JavaLib.store( (objId)"contents", (objId)"list", "iterator" ); hasNext = JavaLib.invoke( (objId)"contents", "hasNext" ); while ( hasNext == 1 ) JavaLib.store( (objId)"myObject", (objId)"contents", "next"); // myObject を処理します hasNext = JavaLib.invoke( (objId)"contents", "hasNext" ); end
// 配列 myArray からコレクションを作成し、 // そのコレクションと ID "list を関連付けます JavaLib.store( (objId)"list", "java.util.Arrays", "asList", (objId)"myArray" );
次に、前のセクションで示したように、list を繰り返します。
配列をコレクションに変換できるのは、オブジェクトの配列の場合に限られます。Java プリミティブの配列をコレクションに変換することはできません。 java.util.Arrays と java.lang.reflect.Array を混同しないように気を付けてください。
多くの場合、Java アクセス関数は、エラー・コードに関連付けられています (関数固有のヘルプのページを参照してください)。 リストされているエラーのいずれかが発生したときに、システム変数 VGVar.handleSysLibraryErrors の値が 1 であると、EGL は、システム変数 sysVar.errorCode にゼロ以外の値を設定します。 エラーのいずれかが発生したときに VGVar.handleSysLibraryErrors の値が 0 の場合は、プログラムが終了します。
sysVar.errorCode の値 "00001000" は、特に重要です。この値は、呼び出されたメソッドにより、またはクラス初期化の結果として、例外がスローされたことを示します。
例外がスローされると、EGL は、それをオブジェクト・スペースに格納します。別の例外が発生すると、2 番目の例外が 1 番目の例外に取って代わります。発生した最後の例外にアクセスするには、ID caughtException を使用します。
特別な状況では、呼び出されたメソッドは、例外だけではなく、OutOfMemoryError や StackOverflowError などのエラーもスローします。この場合、プログラムは、システム変数 VGVar.handleSysLibraryErrors の値に関係なく終了します。
int errorType = 0; Exception ex = null; try { java.io.FileOutputStream fOut = new java.io.FileOutputStream( "out.txt" ); } catch ( java.io.IOException iox ) { errorType = 1; ex = iox; } catch ( java.lang.SecurityException sx ) { errorType = 2; ex = sx; }
VGVar.handleSysLibraryErrors = 1; errorType = 0; JavaLib.storeNew( (objId)"fOut", "java.io.FileOutputStream", "out.txt" ); if ( sysVar.errorCode == "00001000" ) exType = JavaLib.qualifiedTypeName( (objId)"caughtException" ); if ( exType == "java.io.IOException" ) errorType = 1; JavaLib.storeCopy( (objId)"caughtException", (objId)"ex" ); else if ( exType == "java.lang.SecurityException" ) errorType = 2; JavaLib.storeCopy( (objId)"caughtException", (objId)"ex" ); end end end