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 |
| キャストなし、9 から 18 桁 | 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、 |
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 クラスの標準出力ストリームを
// Java System class to the identifier "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