Java データ型

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

概要

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

COBOL と Java 間のデータマッピング

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

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

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

Java データ型の変換規則

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

Java データ型 COBOL データ形式
.cobcall(...) 使用
オブジェクト COBOL データ形式
.cobinvoke() 使用
説明
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

pointer 3

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

pointer 3

pic x(n) 容量はバッファの合計サイズで、サイズはバッファに格納されている文字列の長さ
objects pointer オブジェクト参照 あらゆる Java オブジェクト。手続き型 COBOL では、返されたポインタを JNI 呼出しに使用できる (『Java からの手続き型 COBOL』の章の『COBOL での JNI の使用』の節を参照)。
object[] pointer jarray クラスのインスタンスへのオブジェクト参照 Java オブジェクトの配列。手続き型 COBOL では、返された JNI 呼出しに使用できる (『Java からの手続き型 COBOL の呼出し』の章の『COBOL での JNI の使用』を参照)。jarray は Java 配列の内容にアクセスするためのオブジェクト COBOL クラス (『Jarray クラスの使用』の節を参照)。
DataType 構造体 構造体 複合データ構造体
Comp3 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 jminute 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) (usage 句に national を使用) 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 データ形式」欄と「オブジェクト COBOL データ形式」欄のどちらにも含まれない COBOL データ形式への変換はサポートされていません。ここに挙げられていない型の COBOL データ項目を使用するには、サポートされる型の中間データ項目を使用して、必要なデータ項目の中間データ項目との間でデータを転記します。

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 is true

  JNI-FALSE is false

pic 99 comp-5
jchar pic 9(4) comp-5
jfloat comp-1
jdouble comp-2
jobject pointer
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 jminute pic 99.

0x filler pic x.

0x jseconds pic 99.

脚注:

4.

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

Jarray クラスの使用

jarray クラスは、オブジェクト COBOL で Java 配列を操作するためのラッパーです。詳細は、 『Java Run-time Class Library』で説明されています。

次の 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 "配列は " CDims " 次元です。"

*> 各次元の要素数を取得します。
     display "次元は " 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 "要素 " ind0 ","
                   ind1 " は " 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;
    }
}

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 参照渡しする数値

構造体の使用方法

COBOL プログラムやオブジェクト 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 のコンストラクタを次に示します。

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

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

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

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;
    }
}

サンプルプログラム

本 COBOL 開発システムには、Java から COBOL の構造体にデータを渡す方法を示すサンプルプログラムが付属しています。製品のインストール先の $COBDIR/demo/javademo/oocobol/record$COBDIR/demo/javademo/cobol/record ディレクトリには、サンプルプログラムのすべての関連ファイルと、それらを詳細に説明しているファイル readme.txt が格納されています。