Java メソッドのプロトタイプをコード化する際、戻り値およびパラメーターのタイプを正確に指定しないと、RPG コンパイラーは、メソッド・シグニチャーを不正確にビルドします。 プログラムが実行されると、間違ったメソッドが呼び出されるか、呼び出しが NoSuchMethodError Java 例外で失敗します。
呼び出しが NoSuchMethodError Java 例外で失敗する場合、RPG エラー・メッセージは、メソッドの呼び出しで使用された署名を示します。 以下の表は、Java タイプとメソッド・シグニチャー値の間のマッピングを示します。 Java タイプと RPG タイプ間のマッピングについては、表 30を参照してください。
Java タイプ | 署名 |
---|---|
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
any object | Lclass; |
any array | [type |
Java クラスのメソッド用の有効な署名のリストを表示するには、QSH コマンドを使用します。
javap -s classname
ここで、classname はパッケージと共に指定されます。例: java.lang.String クラスが標準の classpath にない場合は、javap に classpath オプションを指定できます。
javap -s classname -classpath classlocation
メソッド用の有効な署名をメソッド呼び出し用の RPG で使用される署名を比べ、マッピング・テーブルから作業することによって、プロトタイプのエラーを判別できます。
コンストラクターを呼び出すことで、 またはオブジェクトを戻すメソッドを呼び出すことで、 Java オブジェクトを作成した場合、 作成したオブジェクトは解放しない限り存在し続けます。 オブジェクトが解放されるのは次の場合です。
Java メソッドを呼び出す RPG プロシージャーが RPG 固有のメソッドではない場合、 および RPG プロシージャーが、自分が作成したオブジェクトの解放に責任を持たない場合、 そのジョブは結果的にそれ以上オブジェクトを作成できなくなる可能性があります。
次のようなコード・フラグメントがあるとします。
strObject = newString ('abcde'); strObject = trim (strObject); data = getBytes (strObject); freeLocalRef (strObject);
このコードはオブジェクトの解放を引き受けているようですが、 実際にはこのコードは 2 つのオブジェクトを作成します。 1 つ目のオブジェクトは newString() 呼び出しによって作成され、 2 つ目のオブジェクトは trim() 呼び出しによって作成されます。 このコード・フラグメントを訂正するには、以下の 2 つの方法があります。
beginObjGroup(); strObject = newString ('abcde'); strObject = trim (strObject); data = getBytes (strObject); endObjGroup();
strObject = newString ('abcde'); trimmedStrObject = trim (strObject); data = getBytes (trimmedStrObject); freeLocalRef (strObject); freeLocalRef (trimmedStrObject);
Java メソッドをほかの Java メソッドのパラメーターとして呼び出すと、 別の問題が起こることがあります。 次の例では、String パラメーターを取るコンストラクターから BigDecimal オブジェクトを作成しています。
bigDec = newBigDecimal (newString ('12.345')); ... freeLocalRef (bigDec);
このコードの問題は、パラメーターの指定により String オブジェクトが作成されたのに、 RPG プロシージャーはこのオブジェクトを解放できないことです。 この問題を訂正するには、Java を呼び出す RPG コードの前に beginObjGroup() を呼び出し、 後で endObjGroup() を呼び出すか、以下のようにコーディングします。
tempObj = newString ('12.2345'); bigDec = newBigDecimal (tempObj); freeLocalRef (tempObj); ... freeLocalRef (bigDec);
固有のメソッドに静的な Object 変数 (定義に STATIC キーワード) がある場合、 または固有のメソッドが静的なグローバル Object 変数 (メイン・ソース・セクションで宣言した変数) を使用している場合、 その Object 変数は、その固有のメソッドが次に呼び出されるまで値を保持し続けます。 しかし、デフォルトでは、Java は固有メソッドの呼び出し時に作成されたオブジェクトをすべて解放します (Java がオブジェクトを解放しないようにする方法については、 Java を使用するためのその他の RPG コーディングを参照してください)。
RPG の "Object" は実際には数値オブジェクト参照です。 Java オブジェクトが解放されても、この数値オブジェクト参照を再利用することができます。 RPG 固有のメソッドが、明示的に解放の禁止が指定されていない静的な Object 変数を参照すると、 次のいずれかが発生する可能性があります。
オブジェクトの不正な再使用問題を防ぐには、次のようにします。
(C) Copyright IBM Corporation 1992, 2006. All Rights Reserved.