COBOLとJAVAを比較してみた

##    はじめに

  __<font color="blue">　【COBOL(Common Business Oriented Language) = コボル】</font>と__
  __<font color="blue">　【Java = ジャバ】</font>を比較してみました。__

##### COBOLの基本的な記載方法は以下を参照。
https://qiita.com/nano357/items/462a3ec523a3e624340b



# <font color="blueviolet">__データ転記__</font>

 cobol
 ````
 **************************************************************************
        03  END-FLG             PIC  X(3).

   *文字定数転記処理
    MOVE "END" TO END-FLG.
````
java

[オブジェクト指向1](https://qiita.com/nekoozi/items/2cb1d0ed21fa8f12b652)

```java
//クラス※1
public class Example {
 /*public: アクセス修飾子で、このクラスがどこからでもアクセス可能*/
 /*class: クラスを定義するためのキーワード*/
 /*Example: クラスの名前です。クラス名は、通常は大文字で始める*/

    // COBOLのEND-FLGをJavaで表現
    private String endFlg;
    /* フィールド宣言※2 で endFlg を3文字の文字列として宣言  */

    // コンストラクタ
    public Example() {
        this.endFlg = "";
    }
    /* コンストラクタ※3で endFlg を初期化  */


    // getterメソッド
    public String getEndFlg() {
        return endFlg;
    }
    /* getterメソッド※4、※5で endFlg の値を取得  */



    // setterメソッド
    public void setEndFlg(String endFlg) {
     /* void: このメソッドが何も値を返さないことを示す */ 
     /* setEndFlg(String endFlg): メソッドの名前です。
        引数endFlgでフィールドendFlgの値を設定します。 */

        //条件分岐 endFlg が NULL かつ 3文字以下なら 
        if (endFlg != null && endFlg.length() <= 3) {

            //条件分岐 endFlg が NULL かつ 3文字以下なら 
            this.endFlg = endFlg;
            /* this.endFlg = endFlg;: フィールドendFlgに引数のendFlgの値を設定します。*/
            
        } else {
            throw new IllegalArgumentException("endFlg must be a string with a maximum length of 3 characters.");
        }
    }
    /* setterメソッド で endFlg の値を設定 6※～8※   */


    // テスト用のmainメソッド
    public static void main(String[] args) {
     /* main: メソッドの名前です。Javaプログラムのエントリーポイント(プログラムの実行開始地点)として、この名前は特別な意味を持ちます。*/
     /* String[] args: コマンドライン引数を受け取るためのパラメータです。*/
        Example example = new Example();
        /* Exampleクラスのインスタンスを作成します。*/

        example.setEndFlg("END");
        /* 作成したExampleインスタンスのsetEndFlgメソッドを呼び出して、endFlgフィールドに"END"を設定します。*/
        
        System.out.println("End Flag: " + example.getEndFlg());
        /* System: Javaの標準ライブラリのクラスです。*/
        /* out: Systemクラスの標準出力ストリームです。*/
        /* println: 標準出力ストリームに文字列を表示し、改行を行うメソッドです。*/
        
    }
    /* mainメソッド  9※、10※ */
}

```

※1 [Javaのクラスとインスタンス(オブジェクト指向)](
https://qiita.com/mrshouuge/items/675fde85b2af6ddf187b#:~:text=%E3%83%BB%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AF%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%82%92%E4%BD%9C%E3%82%8B,%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E5%AE%A3%E8%A8%80%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%80%82&text=%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AF%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%89%E3%82%8C%E3%81%9F%E5%AE%9F%E4%BD%93%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)

※2 [【Java】フィールド変数](https://qiita.com/takahirocook/items/28df75a133049a74ece1)
※3 [コンストラクタとは](https://qiita.com/shinpachix/items/22934eb9c6cd10efeeea)
※4 [【Java】getter・setterのメモ](https://qiita.com/takahirocook/items/27828bc8477735612021)
※5 [(オブジェクト指向における) getter/setter メソッドの使いどころ](https://qiita.com/CostlierRain464/items/07f46ba005c6c9bb42e2)
※6 [java 条件式とif文](https://qiita.com/chikuwacyan/items/8d3753db4149462d780b)
※7 [可読性を高めるif文の書き方-java](https://qiita.com/nekomaru991/items/454032f5d231f0d65744)
※8 [【Java】throwとthrowsの使い方を簡潔に説明してみる](https://qiita.com/pizza_man0910/items/854858477673b940c4cf)
※9 [【Java】this について](https://qiita.com/takahirocook/items/d251ec4693c68f6b9538)
※10 [【Java】Public static void main(String[] args)の意味](https://qiita.com/kahatato/items/1b4921bb58731f0b7fea)

-------------

# <font color="blueviolet">__制御構造__</font>

 cobol
 ````

PERFORM UNTIL・・・ループを開始する構文です。

 このループは指定された条件が満たされるまで繰り返し実行されます。
 PERFORM UNTIL END-FLG = "END" OR WK-COUNT > 99
    　　　　　　・・・ ループを終了する条件です。
     　　ND-FLGが"END"と等しい　か、
          　　　　　　　　　　　　　WK-COUNTが99を超えると
     　　　　　　　　　ループが終了します。


     READ IN-FILE
     ・・・入力ファイルIN-FILEからレコードを読み取ります。 
     
         AT END
　　         ⇒　入力ファイルの終端に達した場合に実行されるセクションです。
             MOVE "END" TO END-FLG

         NOT AT END
　　         ⇒　入力ファイルの終端に達した場合に実行されるセクションです。

             MOVE IN-FILE-REC TO OUT-FILE-REC
            　・・・入力ファイルのレコードを出力ファイルのレコードにコピーします。
             WRITE OUT-REC
              ・・・WRITE OUT-REC: 出力ファイルにレコードを書き込みます。
             ADD 1 TO WK-COUNT
              ・・・ADD 1 TO WK-COUNT: カウンター変数WK-COUNTに1を加算します。    
    END-READ
    ・・・ READステートメントの終了を示します。
 END-PERFORM.
 ・・・ PERFORMステートメントの終了を示します。

 なお 前提として、
IO-FILEという論理ファイル名を物理ファイル"text01.txt"に割り当てます。
ファイルの組織は行順序（LINE SEQUENTIAL）です。
⇒ファイルの各レコードが1行のデータである可変長のレコードで構成され、復帰文字（CR）または改行文字（LF）で終了することを意味しています。

OUT-FILEという論理ファイル名を物理ファイル"text02.txt"に割り当てます。
ファイルの組織は順編成（SEQUENTIAL）です。
⇒レコードの終端に改行コードがないファイル

END-FLG: 3文字のフラグ変数。
WK-COUNT: 2桁のカウンター変数。
IN-FILE-REC: 入力ファイルのレコードを保持する変数。長さは80文字です。
OUT-FILE-REC: 出力ファイルのレコードを保持する変数。長さは80文字です。
````



 
java
```java
/* ファイルの読み書きと例外処理のパッケージをインポート */
import java.io.BufferedReader;
//ファイルから行単位で効率的に文字データを読み取る

import java.io.BufferedWriter;
//ファイルに行単位で効率的に文字データを書き込む

import java.io.FileReader;
//ファイルから文字データを読み取るために使用

import java.io.FileWriter;
//ファイルに文字データを書き込むために使用

import java.io.IOException;
//入出力操作でエラーが発生した場合にスローされる例外

/* メインクラス */
public class FileProcessingExample {

    /* メインメソッド */
    public static void main(String[] args) {
        String endFlg = ""; //終了フラグ
        int wkCount = 0; //カウンタ変数

        final int RECORD_LENGTH = 80; // レコードの長さを定義する定数
        // * レコードの長さ（80文字）を定義する定数 *//

        
        /* 例外処理のための try ブロックを開始※10
           try-with-resources 構文を使用して、リソースが自動的に閉じられるようにします。※11 */
        try (BufferedReader inFile = new BufferedReader(new FileReader("text01.txt"));
             BufferedWriter outFile = new BufferedWriter(new FileWriter("text02.txt", true))) { // trueで追記モードにする
            /* FileReader を使って、text01.txt ファイルを読み取るための inFile を作成 */
           
            /* FileWriter を使って、text02.txt ファイルに書き込むための outFile を作成します。
               FileWriter のコンストラクタに true を渡すことで、出力ファイル (text02.txt) に追記モードで開きます。
               これにより、既存の内容を消去せずに新しいデータを追加することができます。*/


            StringBuilder inFileRec = new StringBuilder(RECORD_LENGTH); // 長さ80のStringBuilderを使用
            /* StringBuilder: 可変長の文字列を扱うために使用します。 */

            String line;
            while (!endFlg.equals("END") && wkCount <= 99) {
            /* while ループを開始します。このループは endFlg が "END" に等しくない、
                                       かつ wkCount が99以下の間繰り返されます。 ※13  */
            
                // ファイルから1行読み取る
                line = inFile.readLine();

                if (line == null) {
                    endFlg = "END";
                } else {
                    // 読み取った行が80文字未満の場合は、スペースで埋める
                    inFileRec.setLength(0); // StringBuilderをクリアして新しいレコードを処理
                    inFileRec.append(line); // 読み取った行を StringBuilder に追加

                    /* レコードが80文字未満の場合、残りの部分をスペースで埋めます。 */
                    if (inFileRec.length() < RECORD_LENGTH) {

                        //レコードが80文字未満の場合 for文を使う ※13
                        /* ループ変数 i を初期化します。i の初期値として inFileRec.length() を設定しています。
                        　　これは、現在の StringBuilder の長さを取得し、その値を i に設定することを意味します。*/
                        /* i が RECORD_LENGTH （ここでは80）より小さい間、ループが実行されます。
                            つまり、inFileRec の長さが80文字未満の間はループが続きます。*/
                        for (int i = inFileRec.length(); i < RECORD_LENGTH; i++) {
                            inFileRec.append(' '); // スペースで埋める
                        }
                    }

                    // レコードを書き込む
                    outFile.write(inFileRec.toString()); 
                    //改行コードは追加しないことで、データが順編成でそのまま書き込まれます。
                    wkCount++;
                    /*  wkCount を1増加 */
                }
            }

        } catch (IOException e) {
            / * IOException が発生した場合の例外処理を行います */
            e.printStackTrace(); //スタックトレースを出力し、例外の詳細を表示します。
        }
    }
}
```

※11 [Javaの例外処理について](
https://qiita.com/pitan109/items/c9910edddc007126df41)

※12 [try-with-resources文の基本](
https://qiita.com/Takmiy/items/a0f65c58b407dbc0ca99)

※13 [[Java]ループ処理について](
https://qiita.com/taccc_/items/ce71ce41c992341b752e)

-----------------

#### 型とかを厳密に考えると非常に大変なため、
　関連した情報（抜粋：COBOLプログラムを忠実に移植するとなると、COBOLの計算の癖を丁寧に拾って再現させていかなければなりません。読みづらいし、なぜこうしなければならないか説明しづらいソースになります。仕様を当世風に合わせて再定義できればいいんですけど、「動きが変わると困る」とか言われてしまうと大変ですね。）
   　や、関連しそうでしないかも（紹介の仕方が正しくないだけ）情報・その他のトピックのご紹介だけ。
    

[decimal型があるからCOBOLもう要らんやろ、という件について（あるいは十進演算の話）](https://qiita.com/ipponshimeji/items/a89038c58b9466a497ab)

[【Java】データ型・変数・定数](https://qiita.com/takahirocook/items/52298e13281e26e576ab)

[COBOL と Java の相互運用可能なデータ型](https://www.ibm.com/docs/ja/cobol-zos/6.2?topic=statement-interoperable-data-types-cobol-java)

[COBOL2002　ユーザーズガイド 20.3.3　Java言語とCOBOL言語のデータ型の対応](https://itpfdoc.hitachi.co.jp/manuals/3020/30203D6240/USR20347.HTM)

[【俺的】COBOL→Java言語移行ガイド（導入）](https://qiita.com/zama_8722/items/2e9f82a77c9bebfe12a8)

[【COBOL:Java対応チートシート】Java開発者が読み解くCOBOL](https://qiita.com/ymgc3/items/1a7f5d064c3d4b5a2f00)