第 11 章 : Java データ型

この章では、COBOL と Java のデータ型の対応関係について説明します。

11.1 概要

Java 言語では、COBOL で使用されるデータ型とは異なる、Java 用のデータ型が定義されています。図 11-1 に示すように、COBOL から Java (または Java から COBOL) が呼び出されると、COBOL ランタイムシステムによって COBOL と Java 間でデータ型が自動的に変換されます。



図 11-1 : COBOL と Java 間のデータ型のマッピング

数値データ型は、COBOL プログラムが手続き型、オブジェクト指向のどちらで作成されている場合も同じように変換されますが、オブジェクトや文字列の場合はこれらの作成手法によって変換結果が異なります。

Object COBOL では Java オブジェクトは COBOL オブジェクト参照として扱われますが、手続き型 COBOL ではポインタとして扱われます。

11.2 Java データ型の変換規則

COBOL から Java にデータを送信するときには、そのデータが適切な Java データ型に変換されます。 同様に、Java プログラムが COBOL にデータを返信するときにも、Java データ型から COBOL データ型への変換が行われます。 次の表は、Java と COBOL の間でデータがやり取りされるときに実行される型変換を示しています。一部のデータ型は、手続き型 COBOL (『Java からの手続き型 COBOL の呼び出し』の章を参照) と Object COBOL の Java ドメイン (『Object COBOL からの Java の呼び出し』および『Java からの Object COBOL の呼び出し』の章を参照) では扱いが異なる場合があります。 表中の「COBOL」欄は、.cobcall(…) で手続き型 COBOL に適用される規則、「Object COBOL」欄は .cobinvoke() で Object COBOL Java ドメインに適用される規則を示しています。

Java データ型 COBOL Object COBOL 説明
byte pic s99 comp-5 pic s99 comp-5

pic s99 comp

1 バイトの符号付き整数
short pic s9(4) comp-5 pic s9(4) comp-5

pic s9(4) comp

2 バイトの符号付き整数
int pic s9(9) comp-5 pic s9(9) comp-5

pic s9(9) comp

4 バイトの符号付き整数
long pic s9(18) comp-5 pic s9(18) comp-5

pic s9(18) comp 1

8 バイトの符号付き整数
boolean pic 99 comp-5 pic 99 comp-5 0 は false、0 以外の値はtrue
char (Unicode) pic 9(4) comp-5 pic s9(4) comp Java の文字はすべてダブルバイトの Unicode 文字で表される。
float comp-11 comp-1 1 浮動小数点数値
double comp-2 1 comp-2 1 倍精度浮動小数点数値
String mf-jstring 2

ポインタ 3

pic x(n) 容量は常に 0。 COBOL プログラムに渡される文字列は読み取り専用で、変更できないものと考える必要がある。
StringBuffer mf-jstring 2

ポインタ 3

pic x(n) 容量はバッファの合計サイズで、サイズはバッファに格納されている文字列の長さ
objects ポインタ オブジェクト参照 あらゆる Java オブジェクト。手続き型 COBOL では、返されたポインタを JNI 呼び出しに使用できる (『Java からの手続き型 COBOL の呼び出し』の章の『COBOL での JNI の使用』を参照)。
object[] ポインタ jarray クラスのインスタンスへのオブジェクト参照 Java オブジェクトの配列。手続き型 COBOL では、返されたポインタを JNI 呼び出しに使用できる (『Java からの手続き型 COBOL の呼び出し』の章の『COBOL での JNI の使用』を参照)。jarray は、Java 配列の内容にアクセスするための Object COBOL クラス (『Jarray クラスの使用方法』の項を参照)。
DataType 構造体 構造体 複合データ構造体
comp-3 comp-3 comp-3 COMP(UTATIONAL)-3 または PACKED-DECIMAL
Pointer(StringBuffer)

Pointer(String, int capacity)

pic x(99) pic x(99) String や StringBuffer をラップすることによって、正しいサイズが割り当ててられた状態で COBOL プログラムに渡し、COBOL 側で Java オブジェクトを安全に編集できるようにする。

StringBuffer の容量は、COBOL 側で編集可能な最大長として使用される。

java.sql.Date(long)

CobolDate(date)

0x jyear pic 9(4)

0x filler pic x

0x jmonth pic 99

0x filler pic x

0x jday pic 99

cobcall に同じ JDBC で使用される標準 SQL Date 型
java.sql.time(long)

CobolTime(time)

0x jhour pic 99

0x filler pic x

0x jmonth pic 99

0x filler pic x

0x jseconds pic 99

cobcall に同じ JDBC で使用される標準 SQL Time 型

CobolBigDecimal(java.math.BigDecimal)

pic s9(19)v9(19) comp-3 cobcall に同じ COBOL 側での BigDecimal 値の更新を可能にする CobolBigDecimal ラッパークラス。 CobolBigDecimal() のコンストラクタは初期値をとる。更新後の値を取得するには、getValue() メソッドを使用する。

CobolBigInteger(java.math.BigInteger)

pic S9(38) comp-3 cobcall に同じ COBOL 側での BigInteger 値の更新を可能にする CobolBigInteger ラッパークラス。 CobolBigInteger() のコンストラクタは初期値をとる。更新後の値を取得するには、getValue() メソッドを使用する。
CustomRecord 構造体 構造体 Java でオブジェクト配列として表される複合データ構造体
CobolNational pic x(n) の使用は、各国により異なる。 cobcall に同じ UTF-16 文字列を生成して COBOL に渡すための Java クラス。

脚注

1.

参照渡しのみ。浮動小数点データ型の場合、この制約が適用されるのは UNIX プラットフォームに限定されます。long 型の場合は、32 ビットプラットフォームでは参照渡しのみ、64 ビットプラットフォームでは参照渡しと値渡しが可能です。

2.

.cobcall(...) で mf-jstring を使用します。受信側の COBOL プログラムで Java の String または StringBuffer にアクセスするには、ptr2string ポインタを使用する必要があります。mf-jstring を使用すれば、COBOL プログラムから Java オブジェクトのサイズと容量にアクセスできます。

3.

.cobcall(...) でポインタを使用します。

「COBOL」欄と「Object COBOL」欄のどちらにも含まれない COBOL データ型への変換はサポートされていません。 ここに挙げられていない型の COBOL データ項目を使用するには、pic x(n) usageis national.same as forcobcall 型のデータ項目を中間データ項目として使用し、このデータ項目との間で必要に応じてデータを転記します。

11.3 Java データ型の定義

コピーファイル javatypes.cpy には、Java データ型に対応する一連の COBOL データ型が定義されており、Java で使用するデータ項目を COBOL プログラム内で宣言するときに利用できます。 このコピーファイルは $COBDIR/cpylib ディレクトリに格納されています。

これらの型定義を次の表に一覧します。いずれも先頭文字が j になっています。

型定義 COBOL 型
jbyte pic s99 comp-5
jshort pic s9(4) comp-5
jint pic s9(9) comp-5
jlong pic s9(18) comp-5
jboolean

JNI-TRUE:true

JNI-FALSE:false

pic 99 comp-5
jchar pic 9(4) comp-5
jfloat comp-1
jdouble comp-2
jobject ポインタ
jbigdecimal pic s9(19)v9(19) comp-3 4
jbiginteger pic s9(38) comp-3 4
mf-sql-date

(javatypes.cpy での定義)

0x jyear pic 9(4)

0x filler pic x

0x jmonth pic 99

0x filler pic x

0x jday pic 99

mf-sql-time

(javatypes.cpy での定義)

0x jhour pic 99

0x filler pic x

0x jmonth pic 99

0x filler pic x

0x jseconds pic 99

脚注

4.

これらの型を使用するすべてのプログラムは、intlevel 4 指令でコンパイルする必要があります。

11.4 Jarry クラスの使用方法

jarray クラスは、Object COBOL で Java 配列を操作するためのラッパーです。 詳細については、docs/mfcobol.docs.zip に格納されている『Java Run-time Class Library Reference』で説明されています。

次の COBOL プログラムは Java オブジェクトから配列を受け取り、次元を検出して、配列の内容を表示します。

$set ooctrl (+p-f)
 Program-id. ReadArray.
 class-control.
     arraydemo is class "$Java$arraydemo"
     .

 thread-local-storage section.
 01 aJavaObj             object reference.

 01 theTotal        pic 9(9).
 01 CDims           pic x(4) comp-5.
 01 Dims.
   03 Dims-entry    pic x(4) comp-5 occurs 256.
 01 Bounds.
   03 Bounds-entry  pic x(4) comp-5 occurs 256.
 01 ind0            pic x(4) comp-5.
 01 ind1            pic x(4) comp-5.
 01 arrayElement    pic x(4) comp-5.
 01 wsTable         object reference.
 01 wsResult        pic x(4) comp-5.

 procedure division.
   invoke arraydemo "new" returning aJavaObj
   invoke aJavaObj "getArray" returning wsTable

*> 配列内の要素数を検出します。
     invoke wsTable "getDimensions" returning CDims
     display "The array has " CDims " dimension(s)"

*> 各次元の要素数を取得します。
     display "dimensions are " with no advancing
     invoke wsTable "getBounds" using Bounds
     perform varying ind0 from 1 by 1 until ind0 > CDims
          display Bounds-entry(ind0) with no advancing
          if ind0 < CDims
             display " by " with no advancing
          end-if
     end-perform
     display " "

*> 配列内の各要素を表示します。
     perform varying ind0 from 0 by 1
             until ind0 = Bounds-entry(1)
         move ind0 to Dims-entry(1)
         perform varying ind1 from 0 by 1
                   until ind1 = Bounds-entry(2)
             move ind1 to Dims-entry(2)
             invoke wsTable "getElement" using
                             by value CDims
                             by reference Dims
                             by reference arrayElement
             display "Element " ind0 ","
                   ind1 " is " arrayElement
*> 配列の内容を変更します。
             add 50 to arrayElement
             invoke wsTable "putElement" using
                             by value CDims
                             by reference Dims
                             by reference arrayElement
         end-perform
     end-perform

この ReadArray プログラムで使用される arraydemo クラスの実装を次に示します。 このプログラムは 2 次元配列を生成します。

import com.microfocus.cobol.*;
import java.io.*;

public class arraydemo extends RuntimeSystem
{
    int myArray[][];
    public arraydemo()
    {
        myArray = new int[5][2];
        int i,j;
        for (i = 0; i < 5; i++)
        {
            for (j = 0; j < 2; j++)
                myArray[i][j] = i * 100 + j;
        }
    }
    public int[][] getArray()
    {
        return myArray;
    }
}

11.5 ParameterList() によるパラメータの追加

com.microfocus.cobol.lang で定義されている ParameterList() クラスは、Java と COBOL の間でパラメータをやり取りする手段として役立ちます。

ParameterList() は通常、次の形式で使用します。

   RuntimeSystem.cobcall("myProgram", 
    new ParameterList()
        .add(myOneInt,RuntimeSystem.BY_VALUE)
        .add(mySecondParameter,RuntimeSystem.BY_REFERENCE)
	       .add(99)		// 数値 99 の参照渡し
	       );

説明

myProgram 呼び出すプログラムの名前
myOneInt 値渡しする整数型パラメータ
mySecondParameter 参照渡しするパラメータ
99 参照渡しする数値

11.6 構造体の使用

COBOL プログラムや Object COBOL のメソッドでは、連絡節で構造体を使用し、Java クラスから渡されたデータをその中に格納することが可能です。ただし、対応する Java 側のパラメータが、com.microfocus.cobol.lang.Datatype または com.microfocus.cobol.lang.CustomRecord を実装したオブジェクトであることが前提になります。次にこれらのインターフェイスの定義を示します。

package com.microfocus.cobol.lang;
public interface DataType
{
   void synchronizeData();
   byte[] getBytes();
}

および

package com.microfocus.cobol.lang;
public interface CustomRecord
{
   public Object[] getParameters();
   public void setParameters(Object[] parms);
}

com.microfocus.cobol.lang.Datatype/com.microfocus.cobol.lang.CustomRecord を使用すれば、複雑な構造のデータを COBOL のプログラムやメソッドに渡すことができます。多数の基本データ型でインターフェイスを作り直す必要はありません。

com.microfocus.cobol.lang.Datatype インターフェイスを実装したクラスの一例が、mfcobol.jar で定義されている com.microfocus.cobol.lang.Pointer です。 com.microfocus.cobol.lang.Pointer のコンストラクタを次に示します。

/* 文字列 initString から Pointer オブジェクトを作成します*/
public Pointer(String initString); 

/* StringBuffer initString から Pointer オブジェクトを作成します */
public Pointer(StringBuffer initString); 

/* 'capacity' で指定するバイト数を含む Pointer オブジェクトを作成します */
/* initString の文字数が capacity より小さい場合、余剰部分は     */
/* 空白文字で埋められます'                                      */
public Pointer(String initString, int capacity); 

11.7 com.microfocus.cobol.lang.CustomRecord インターフェイスによるカスタムレコードの作成

既存の COBOL プログラムにグループ項目を渡す場合にカスタムレコードを使用すると便利です。 カスタムレコードは .cobcall メカニズムとともに使用します。

CustomRecord インターフェイスの定義を次に示します。

package com.microfocus.cobol.lang;
public interface CustomRecord
{
  public Object[] getParameters();
  public void setParameters(Object[] parms);
}

RecordDemo2 の customerDetails は次のように定義されています。

  01 customerDetails.
         03 customerName       pic x(30).
         03 customerAddress    pic x(30).
         03 customerRef        pic 9(6).

Java による CustomRecord インターフェイスの実装例を次に示します。

import com.microfocus.cobol.lang.*;
import java.text.*;
public class RecordData implements 
       com.microfocus.cobol.lang.CustomRecord  
{
    private String customerName;
    private StringBuffer customerAddress;
    private int customerRef;
    RecordData(String name, String address, int ref)
    {
        customerName = name;
        customerAddress = new StringBuffer(address);
        customerRef = ref;
    }
    public String getCustomerName()
    {
      return this.customerName;
    }
    public String getCustomerAddress()
    {
      return this.customerAddress.toString();
    }
    public int getCustomerRef()
    {
      return this.customerRef;
    }
    public Object[] getParameters()
    {
     String strCustomerRef = 
            Integer.toString(this.customerRef);    	
     while(strCustomerRef.length() <  6)
     {
        strCustomerRef = "0"+strCustomerRef;
     }
     customerAddress.setLength(30);        
            /* 必ず正しい長さを指定する。 */
     customerAddress.ensureCapacity(30);
     return new ParameterList()
        .add(new Pointer(this.customerName,30))
        .add(this.customerAddress)
        .add(strCustomerRef.getBytes())
        .getArguments();
    }

    public void setParameters(Object[] parms)
    {
      Pointer ptr = (Pointer)parms[0];
      this.customerName = ptr.toString(); 
      this.customerAddress = (StringBuffer)parms[1];
      byte[] byteCustomerRef = (byte[])parms[2];
      this.customerRef = 
            Integer.parseInt(new String(byteCustomerRef));
    }
    public String toString()
    {
      return "Customer Name    : "+this.customerName+"\n"+
          "Customer Address : "+this.customerAddress+"\n"+
          "Customer Ref     : "+this.customerRef;
    }
}

11.8 デモンストレーションプログラム

COBOL 開発システムには、Java から COBOL の構造体にデータを渡す方法を示すデモンストレーションプログラムが付属しています。 デモンストレーションプログラム関連のファイルは、製品のインストール先ディレクトリであるdemo/javademo/oocobol/record フォルダと demo/javademo/cobol/record フォルダに含まれています。これらのフォルダには、デモンストレーションプログラムの詳細を説明する readme.txt ファイルもあります。


Copyright © 2004 Micro Focus International Limited. All rights reserved.