Java™ アクセス関数は、EGL システム関数です。これは、ユーザーの Java コードを使用したローカル Java オブジェクトおよびクラスへのアクセスに使用されます。 特に、これらの関数は、public メソッド、コンストラクター、およびローカル・コードのフィールドにアクセスします。これらは、EGL が以前のバージョンとの互換性のためにのみ保守している古い関数です。新規コードの場合は、より強力な ExternalType 構文を使用してください。詳しくは、『ExternalType パーツ』を参照してください。
この EGL フィーチャーは、実行時に EGL Java オブジェクト・スペース が存在する場合に使用可能になります。EGL Java オブジェクト・スペースは、一連の名前とそれらの名前 が参照するオブジェクトです。生成したプログラムとそれらのプ ログラムがローカルで呼び出すすべての生成済み Java コードで、単一のオブジェクト・スペースを使用できます。呼 び出しが直接呼び出しであるか別のローカル生成された Java プログラムを介して いるかにかかわらず、任意のレベルの呼び出しで使用できます。オブジェクト・スペースは、 いずれのローカル Java コードでも使用できません。
オブジェクトをオブジェクト・スペースで格納および検索するには、Java アクセス関数を呼び出します。呼び出しでは識別子も使用します。各識別子は、オブジェクトを格納したり、既にオブジェクト・スペースに存在する名前と一致させるために使用されるストリングです。 ID が名前と一致すると、コードからその名前に関連付けられ たオブジェクトにアクセスできます。
メソッドに渡すそれぞれの引数 (およびフィールドに代入するそれぞれの値) は、Java オブジェクトまたはプリミティブ型にマップされます。詳しくは、『EGL プリミティブ型の Java へのマッピング』を参照してください。
Java アクセス関数を組み込んだ EGL コードを COBOL プログラムとして生成することはできません。
このセクションでは、 Java アクセス関数の使用方法について例を示します。
// 識別子の名前を CHAR 型の変数に代入します
valueID = "osNameProperty"
// プロパティー os.name の値を
// オブジェクト・スペースに格納し、この値 (Java の String) を ID osNameProperty に
// 関連付けます
javaLib.store(valueId as "objID:java", "java.lang.System",
"getProperty", "os.name");
// プロパティー値が存在しないかどうかをテストし、
// それに応じて処理を実行します
myNullFlag = javaLib.isNull( valueId as "objID:java" );
if( myNullFlag == 1 )
error = 27;
end
EGL で Java 配列を扱うときは、java.lang.reflect.Array Java クラスを使用します (詳しくは、Java API ドキュメンテーションの説明を参照してください)。Java 配列はコンストラクターを持たないため、 javaLib.storeNew() を使用して Java 配列を作成することはできません。
オブジェクト・スペースに配列を作成するには、java.lang.reflect.Array の静的メソッド newInstance() を使用します。 配列を作成した後で、そのクラスの他のメソッドを使用して、要素にアクセスします。
Class オブジェクトを識別するコードは、オブジェクト配列、または基本配列のどちらを作成するかによって変わります。 次のセクションの例で、このバリエーションを示します。
// newInstance() で使用するために、クラスへの参照を取得します
javaLib.store( "objectClass" as "objID:java", "java.lang.Class",
"forName", "java.lang.Object" );
// オブジェクト・スペース内に配列を作成します
javaLib.store( "myArray" as "objID:java", "java.lang.reflect.Array",
"newInstance", "objectClass" as "objID:java", 5 );
異なる型のオブジェクトを保持する配列を作成するには、javaLib.store() の最初の呼び出しに渡すクラス名を変更してください。 String オブジェクトの配列を作成するには、例えば、 java.lang.Object の代わりに java.lang.String を渡します。
length = javaLib.invoke( "java.lang.reflect.Array",
"getLength", "myArray" as "objID:java" );
i = 0;
while ( i < length )
javaLib.store( "element" as "objID:java", "java.lang.reflect.Array",
"get", "myArray" as "objID:java", i );
// ここで、適宜要素を処理します
javaLib.invoke( "java.lang.reflect.Array", "set",
"myArray" as "objID:java", i, "element" as "objID:java" );
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( "intClass" as "objID:java",
"java.lang.Integer", "TYPE");
// オブジェクト・スペース内に配列を作成します
javaLib.store( "myArray2" as "objID:java", "java.lang.reflect.Array",
"newInstance", "intClass" as "objID:java", 30 );
異なる型のプリミティブを保持する配列を作成するには、javaLib.storeField() の呼び出しに渡すクラス名を変更してください。 文字の配列を作成するには、例えば、java.lang.Integer の代わりに java.lang.Character を渡します。
length = javaLib.invoke( "java.lang.reflect.Array",
"getLength", "myArray2" as "objID:java" );
i = 0;
while ( i < length )
element = javaLib.invoke( "java.lang.reflect.Array",
"getDouble", "myArray2" as "objID:java", i );
// ここで、適宜要素を処理します
javaLib.invoke( "java.lang.reflect.Array", "setDouble",
"myArray2" as "objID:java", 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( "contents" as "objID:java",
"list" as "objID:java", "iterator" );
hasNext = javaLib.invoke( "contents" as "objID:java", "hasNext" );
while ( hasNext )
javaLib.store( "myObject" as "objID:java",
"contents" as "objID:java", "next");
// myObject を処理します
hasNext = javaLib.invoke( "contents" as "objID:java", "hasNext" );
end
// 配列 myArray からコレクションを作成し、
// そのコレクションと ID "list を関連付けます
javaLib.store( "list" as "objID:java", "java.util.Arrays",
"asList", "myArray" as "objID:java" );
次に、前のセクションで示したように、list を繰り返します。
配列をコレクションに変換できるのは、オブジェクトの配列の場合に限られます。 Java プリミティブの配列をコレクションに変換することはできません。 java.util.Arrays と java.lang.reflect.Array を混同しないように注意してください。
デフォルトのエラー処理 (v60ExceptionCompatibility を NO に設定) を使用している場合、 呼び出された Java コードが例外をスローすると、EGL は JavaObjectException をスローすることによって応答します。EGL 側のエラーは、RuntimeException を引き起こします。 個々の関数の『エラーに関する考慮事項』も参照してください。
V6 の例外互換性を使用する場合 (『v60ExceptionCompatibility』を参照)、javaLib 内の関数によって設定される sysVar.errorCode の値を使用できます (これらの関数についての個々のトピックで説明しています)。
sysVar.errorCode の値 "00001000" は、特に重要です。この値は、呼び出されたメソッドにより、またはクラス初期化の結果として、例外がスローされたことを示します。
例外がスローされると、EGL は、それをオブジェクト・スペースに格納します。別の例外が発生すると、2 番目の例外が 1 番目の例外に取って代わります。発生した最新の例外にアクセスするには、識別子 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( "fOut" as "objID:java",
"java.io.FileOutputStream", "out.txt" );
if ( sysVar.errorCode == "00001000" )
case ( javaLib.qualifiedTypeName( "caughtException" as "objID:java" ) )
when ( "java.io.IOException" )
errorType = 1;
javaLib.storeCopy( "caughtException" as "objID:java",
"ex" as "objID:java" );
when ( "java.lang.SecurityException" )
errorType = 2;
javaLib.storeCopy( "caughtException" as "objID:java",
"ex" as "objID:java" );
end
end