Add JavaSrc: cobol-tna-system COBOL->Java conversion (ZAN01-06/KIN01-09/KYU01-09 + 变换规则 doc)

This commit is contained in:
opencode
2026-08-29 20:50:08 +08:00
parent c9ea370397
commit f99f6696a6
71 changed files with 15350 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
# 既存 COBOL コード不備点 調査記録
- **作成日**: 2026-08-25
- **背景**: KIN0109 / ZAN0106 の COBOL→Java 変換後、Java↔COBOL↔設計書 の三方照合を実施。本ファイルは「既存 COBOL 側に存在する不備・設計書からの乖離」を記録し、後続調査・対応の起点とする。
- **関連成果物**:
- 修正済 Java: `src/Sub05TimSub.java`(丸め), `src/Kin07DaiMain.java`(未知休暇型), `src/dto/Kin03Rec.java`(数値埋込), `src/Zan03ChkMain.java`(休日フラグ互換), `src/util/ConvUtil.java`(padLeftZero 追加)
- COBOL 側マーキング: 各対象行に `COBOL-DEFICIENCY:` コメントを付与済(参照先=本ファイル)
---
## 1. 照合結果サマリ(全 30 項目)
判定: ◯=一致(無影響) △=軽差/条件無影響 ✗=差異(有影響)
| 模块 | 文件 | 判定 | COBOL 側問題? | 備考 |
|------|------|------|--------------|------|
| ZAN01 | Zan01ChkMain | ◯ | | trim/再符号化のみ |
| ZAN02 | Zan02ChkMain | ◯ | | キー比較のみ条件差 |
| **ZAN03** | Zan03ChkMain | ✗ | **C類** | 休日フラグ値('1')設計未規定/運用慣習 |
| ZAN04 | Zan04MatMain | ◯ | | |
| **ZAN05** | Zan05CalMain | ✗ | (COBOL正) | Java 側真缺陷(丸め)→已修 |
| ZAN06 | Zan06UpdMain | ◯ | | ADD は COBOL と一致 |
| **KIN01** | Kin01InpMain | ✗ | **A類** | フィールド数ゲート off‑by‑one |
| KIN02 | Kin02UpdMain | ◯ | | |
| KIN03 | Kin03ExpMain | ◯ | | |
| **KIN04** | Kin04ChkMain | ✗ | **A類** | フィールド数ゲート off‑by‑one |
| **KIN05** | Kin05MatMain | ✗ | **A類** | WRKBEST 未リセット |
| KIN06 | Kin06CldMain | △ | **D類**(条件) | 休日全件取込≤50 件の上限リスク |
| KIN07 | Kin07DaiMain | △ | (COBOL正) | Java 側真缺陷(未知型)→已修 |
| **KIN08** | Kin08DbuMain | ✗ | **B類** | RESET で MONTHLY のみ削除/T カード 10 名上限 |
| **KIN09** | Kin09CsvMain | ✗ | **B類** | FULL/SHORT 出力範囲反転/時間欄書式 |
| SUB01 | Sub01DatSub | △ | | TZ 依存(条件) |
| SUB02 | Sub02MsgSub | ◯ | | |
| SUB03 | Sub03EndSub | ◯ | | |
| SUB04 | Sub04ChkSub | △ | | parseInt vs NUMVAL(条件) |
| SUB05 | Sub05TimSub | △ | | double 精度(条件) |
| PAR DTO群 | Zan*Par/Kin*Rec 等 | ◯ | | |
| **Kin03Rec** | dto/Kin03Rec | △ | (copybook正) | Java 側真缺陷(埋込)→已修 |
| EmpRec | dto/EmpRec | | | COBOL 対応物なし(照合不可) |
---
## 2. COBOL 側不備の詳細分類
### A 類:COBOL 自身のバグ(Java は設計書通りに修正済)
#### A1. KIN01INP — フィールド数ゲート誤り
- **ファイル:行**: `cobol/KIN01INP.cbl:250` `IF WRK-COMMA-CNT NOT = 8`
- **COBOL 挙動**: `WRK-COMMA-CNT``UNSTRING ... TALLYING` の**区切り数**(8 フィールド→7)。`7 ≠ 8` が常真となり、形式正しい 8 フィールド行も全て `F` エラー(W02) へ振分け。
- **設計指定**: 設計書は「フィールド数=8」で判定。
- **Java 挙動**: `tokens.length == 8` で判定(設計通り)。→ COBOL と W01/W02 が逆転。
- **COBOL 側問題**: 明確な offbyone バグ。
- **対応**: Java は設計準拠で正。COBOL 側はレガシー不備。修正不要(Java 維持)。
#### A2. KIN04CHK — フィールド数ゲート誤り(同上)
- **ファイル:行**: `cobol/KIN04CHK.cbl:271,293` `IF WRK-COMMA-CNT = CNS-FIELD-COUNT-6(=6)`
- **COBOL 挙動**: 区切り数は 5。`5 = 6` は常偽 → 以降の 4 段検証が実行されず、正しい 6 フィールド行も W02 へ。
- **設計指定**: フィールド数=6。
- **Java 挙動**: `tokens.length == 6`(設計通り)。
- **対応**: Java 維持。COBOL 側バグ。
#### A3. KIN05MAT — WRKBEST 未リセット(情報リーク)
- **ファイル:行**: `cobol/KIN05MAT.cbl:400` `2100R01ONLYSOR SECTION.`R01 単独出力)
- **COBOL 挙動**: `1000ITTSOR`/`2020MATCHSOR` のみ `WRK-BEST-*` を初期化。`2100R01ONLYSOR`(マッチ直後の「休暇なし R01」) ではリセットせず、**直前のマッチの休暇情報(LEAVE‑TYPE/APPLID)がそのまま出力**される。
- **設計指定**: R01 単独 → '99' 初期化(設計書「R01 単独は '99'」)。
- **Java 挙動**: 各 R01 で `resetBest()` を実施(設計通り)。
- **対応**: Java 維持。COBOL 側バグ。
### B 類:COBOL が設計書から乖離(Java は設計書通り=正)
> これらは「COBOL の挙動が設計と食い違っている」点。Java を COBOL に合わせて戻すと**設計違反**になる。原則として **Java を維持**し、COBOL 側を不備として記録する。
#### B1. KIN09CSV — FULL/SHORT 出力範囲が設計と逆
- **ファイル:行**: `cobol/KIN09CSV.cbl:160` `IF MODE-SHORT PERFORM 2500-SHORT-MODE`
- **COBOL 挙動**: 日別行は常時出力、`MODE-SHORT` 時にのみサマリ追加 → **FULL=日別のみ / SHORT=日別+サマリ**
- **設計指定**: PARM 表 `FULL=日別+月次 / SHORT=月次のみ`(詳細設計書_KIN09CSV L33)。
- **Java 挙動**: 設計通り `FULL=日別+サマリ / SHORT=サマリのみ`
- **対応**: **Java 維持**。COBOL が設計と逆。※設計書 §3 見出し「SHORT 時のみ追加処理」も矛盾含み(設計書自身の不備、後述)。
#### B2. KIN09CSV — 時間欄編集書式
- **COBOL 挙動**: `PIC Z(3)9.9` → 先頭空白(例 `" 8.0"`)。
- **設計指定**: CSV 例 `8.0`(先頭空白なし)。
- **Java 挙動**: 先頭空白なし(設計例通り)。
- **対応**: **Java 維持**(設計例に合致)。COBOL が設計例と食い違い。
#### B3. KIN08DBU — RESET で MONTHLY のみ削除(DAILY を削除しない)
- **ファイル:行**: `cobol/KIN08DBU.cbl:488` `DELETE FROM MONTHLY_ABSENCE`
- **COBOL 挙動**: RESET 時に `MONTHLY_ABSENCE` のみ削除。`DAILY_RECORDS` は削除せず、再実行時に PK 衝突で ABEND リスク。
- **設計指定**: 使用 DB 表(L45)・SYSIN 仕様(L29)「RESET=既存削除後再 INSERT」→ **DAILY_RECORDS も DELETE+INSERT**
- **Java 挙動**: RESET で DAILY+MONTHLY 両削除(設計通り)。
- **対応**: **Java 維持**。COBOL が設計と乖離(設計書ステップ 3‑1 に MONTHLY 削除しか書かれておらず記述漏れ)。
#### B4. KIN08DBU — T カード対象社員 10 名上限
- **ファイル:行**: `cobol/KIN08DBU.cbl:294` `UNSTRING ... INTO TARGET-EMP(1)...(10)`
- **COBOL 挙動**: `UNSTRING` の受信側が `(1)..(10)` のみ(テーブルは OCCURS 100 だが実質 10 名まで)。11 名目以降は集計から漏れる。
- **設計指定**: T カード上限の記載なし(無制限扱い)。
- **Java 挙動**: 全件格納(設計通り、無制限)。
- **対応**: **Java 維持**。COBOL 側の実装上限制(設計未記載のため、COBOL の制限を「仕様」とみなすか要合意)。
### C 類:設計書未規定/データ慣習
#### C1. ZAN03CHK — 休日フラグ値の指定欠落
- **ファイル:行**: `cobol/ZAN03CHK.cbl:385` `IF WRK-HD-FLG(...) = '1'`
- **COBOL 挙動**: 休日カレンダ(ZAN03R03.DAT) のフラグが `'1'` のとき `OVT-TYPE='H'`
- **設計指定**: 設計書は「休日→'H'/平日→'W'」の**出力セマンティクスのみ**規定し、**入力フラグ値('1'/'H'/他)を一切規定せず**。
- **Java 挙動(修正後)**: `'1'``'H'` の両方を受容(運用互換)。
- **COBOL 側問題**: COBOL が `'1'` を前提としており、設計書がフラグ値を規定していない**設計書側の欠落**。COBOL 自体は「運用慣習通り」で動く。
- **対応**: 設計書へ「フラグ='1' で休日」と追記推奨。Java は両対応済。
### D 類:条件付きリスク(COBOL 側潜在不備)
#### D1. KIN06CLD — 休日取込上限 50 件
- **ファイル:行**: `cobol/KIN06CLD.cbl` `1200HOLIDAYSOR`SELECT 全件 ORDER BY、但し `HOLIDAY-COUNT < 50` で打切り)
- **COBOL 挙動**: 休日を最大 50 件までしかロード。対象月の休日が 50 件目以降に位置する場合、一部が「出勤日」と判定される。
- **Java 挙動**: 対象月のみロード(同様に 50 件上限)。
- **影響**: 通常 <50 件で無影響。休日マスタが 50 件を超える環境では双方にリスク(COBOL 由来の制約)。
- **対応**: 本番マスタ件数を確認;超える場合は COBOL/Java 双方で上限緩和を要検討。
---
## 3. Java 側真缺陷(本調査で発見・既に修正済)
参考として、COBOL ではなく **Java 側にあった真の缺陷**を記録(いずれも修正完了)。
| 項目 | ファイル | 修正内容 |
|------|----------|----------|
| ZAN05 丸め | Sub05TimSub.java | `Math.round``Math.floor`(設計=0.1h 切捨) |
| KIN07 未知休暇型 | Kin07DaiMain.java | 未知型を無視(W02 非出力)に変更 |
| Kin03Rec 数値埋込 | dto/Kin03Rec.java | `padRight``padLeftZero`(前ゼロ)+ ConvUtil に `padLeftZero(String,int)` 追加 |
| ZAN03 フラグ互換 | Zan03ChkMain.java | フラグ `'1'``'H'` の両方を受容 |
---
## 4. 設計書自身の矛盾(COBOL/Java 双方に関係)
1. **KIN09CSV 詳細設計書**: PARM 表(L33) `FULL=日別+月次` に対し、§3 見出し「SHORT 時のみ追加処理(2500SHORT‑MODE)」が逆のニュアンス。正規定義は PARM 表。→ Java は PARM 表準拠(正)。
2. **KIN08DBU 詳細設計書**: ステップ 31 に `MONTHLY_ABSENCE` 削除のみ記載され、`DAILY_RECORDS` 削除が抜けている(使用 DB 表表・SYSIN 仕様からのみ読取可)。→ Java は両削除(正)。
3. **ZAN03CHK**: 休日フラグ値の規定なし(C‑1)。
---
## 5. 推奨対応方針
- **A 類 (KIN01/04/05)**: COBOL バグ。Java は設計準拠で正 → **Java 維持**。COBOL 側をレガシー不備として本ファイルに記録。業務確認の上、COBOL を「仕様通り(バグ有)」で据え置くか別途 COBOL 修正するか決定。
- **B 類 (KIN09/KIN08)**: COBOL が設計から乖離。Java は設計準拠 → **Java 維持**。COBOL 側を不備記録。**厳密な COBOL 出力パリティ(並行運用比較等)が必要な場合のみ**、Java に「COBOL 互換モード」フラグを検討(要合意)。
- **C 類 (ZAN03)**: 設計書へフラグ値('1')を追記。Java は両対応済。
- **D 類 (KIN06)**: 本番休日マスタ件数を確認し、50 件超なら双方で上限緩和。
- **設計書矛盾**: 上記 3 点を設計書へ反映(設計側修正)。
---
*本ファイルは調査記録であり、コード変更は別途チケット/PR で管理すること。COBOL 側マーキング箇所は各 `.cbl` 内の `COBOL-DEFICIENCY:` コメントを参照。*
+362
View File
@@ -0,0 +1,362 @@
# Java版 测试基准说明
> **出典**: COBOL测试基准说明.md(程序分类及测试基准.pdf 第2部)のJava转换工程向け适配版
> **用途**: 步骤5【验证】制定每轮测试计划时使用,结果记入对照表《验证结果》。
## 适用性标注
| 记号 | 意味 |
|---|---|
| ✅ | 适用(本轮或该类型程序出现即实施) |
| ⚠️ | 部分适用・等价确认 |
| ➖ | 当前不适用(附复活条件) |
| ◎ | 必须测试(来自原基准) |
| ○ | 推荐测试(来自原基准) |
## 一、主机概念 ↔ Java 对应
| 主机概念 | Java等价物 | 确认方法 |
|---|---|---|
| JOB / JOBLOG | java命令执行 + 标准输出重定向 | 日志文件 `data\test_程序名.log` 保存检查 |
| RETURN-CODE = 0 | 进程退出码 0 | `echo %ERRORLEVEL%` |
| ABEND Uxxxx / STOP RUN | System.exit(999)Windows实际退出码=999%256=**231** | ERRORLEVEL=231 ABEND消息 |
| OPEN FILE STATUS 35 | FileNotFoundException → UncheckedIOExceptionJVM退出码1 | 异常堆栈 ERRORLEVEL≠0 |
| FILE STATUS 各值 | 异常机制 / 定长DTO的结构保证 | 见各行基准 |
| SYSOUT | 标准输出 | 与JOBLOG同一控制台流 |
| FB/VB顺序文件 | 文本文件(UTF-8无BOM),1行=1记录;VB不输出RDW前缀 | fc 比对 |
| VSAM(KSDS/RRDS/ESDS) | 未出现(出现时另行定义映射) | — |
| EBCDIC/SJIS编码变换 | 不适用:本工程统一UTF-8 | — |
---
## 二、通用执行手顺
```
1. compile.bat → Compile OK.
2. 准备输入 data\<用例>.csv → 每用例一组文件
3. java -Dfile.encoding=UTF-8 -cp out 程序名 > data\test_程序名.log 2>&1
4. echo %ERRORLEVEL% → 记录退出码
5. fc /b data\期望文件.txt data\实际输出.txt → 每个输出文件逐一比对
6. 结果记入对照表《验证结果》
```
### Java侧特有注意事项(与主机行为的固有差异,测试时必须意识到)
| # | 差异点 | 内容 | 对测试的影响 |
|---|---|---|---|
| J1 | 退出码 | 有两条ABEND路径:① 文件I/O异常(IOException)→UncheckedIOException→JVM默认退出码1;② 业务逻辑ABENDSUB01DAT失败等)→abendPara()→System.exit(999)→Windows实际231 | 路径①期望退出码1;路径②期望231+ABEND CODE消息 |
| J2 | 行分隔符 | println在Windows输出CRLF\\r\\n | 期望文件须同方式生成后fc比对 |
| J3 | BOM | OutputStreamWriter("UTF-8")不写BOM | fc /b首字节应为记录内容 |
| J4 | 字符vs字节 | Java substring/padRight按char计;PIC X(n)按byte计 | 全角混入时定长记录字节数会变(数据限半角方针;VF-A002单独验证行为) |
| J5 | 数值溢出 | int溢出静默绕回≠COBOL高位截断 | NP-A004必测 |
| J6 | SIZE ERROR | Java无自动ON SIZE ERROR分支,转换时须显式实现 | NP-N003必查实现存在性 |
| J7 | WRITE异常 | PrintWriter吞IOExceptioncheckError | 磁盘满等异常无法检测→COM-A005不适用理由之一 |
| J8 | 输出覆盖 | FileOutputStream已有输出时覆盖写入 | 幂等性RR-N001天然满足;主机侧再执行需先删文件 |
| J9 | BigDecimal精度 | BigDecimal运算的scale/precision须与式样书指定的PIC(n)V9(m)完全一致 | NP-N002必查:scale=m、intLen=n、ROUNDING=HALF_UP,三者缺一不可 |
---
## 三、正常系通用基准(对应2.1.1)
| 编号 | 项目 | 内容 | 优先级 | 适用 | Java中的做法 |
|---|---|---|---|---|---|
| COM-N001 | 最小数据(1条) | 各输入文件1条 | ◎ | ✅ | 每程序至少1组单件用例 |
| COM-N002 | 标准数据(多条) | 正常业务量 | ◎ | ✅ | 正常业务量用例(如KIN01INP的7件) |
| COM-N003 | 最大数据(上限) | 定义上限(含性能) | ○ | ✅ | 生成脚本造大量数据测性能(10万件) |
| COM-N004 | 全部输出文件存在 | 期望输出文件全部生成 | ◎ | ✅ | dir确认 + 件数消息比对 |
| COM-N005 | 输出文件内容确认 | 与期望值完全一致 | ◎ | ✅ | fc /b 逐字节比对每个输出文件 |
| COM-N006 | 输出记录长度确认 | 与规格一致 | ◎ | ✅ | 定长记录字节数检查(80B + 换行符);期望文件须同方式生成(J2) |
| COM-N007 | 输出排序确认 | 键序正确 | ◎ | ⚠️ | 仅当程序有排序/键序输出时适用 |
| COM-N008 | JOBLOG确认 | 日期/件数/结束码 | ◎ | ✅ | 控制台日志保存为 data\test_程序名.log,确认开始/件数/终了消息与退出码0 |
---
## 四、异常系通用基准(对应2.1.2)
| 编号 | 项目 | 内容 | 期望结果 | 优先级 | 适用 | Java中的做法 |
|---|---|---|---|---|---|---|
| COM-A001 | 文件不存在 | 不存在文件 | OPEN STATUS 35 ABEND | ◎ | ✅ | 文件读取异常→UncheckedIOException→退出码1;业务ABEND→exit(999)→退出码231(两条路径见J1 |
| COM-A002 | 全部0件 | 所有输入为空 | 正常结束 输出0条 | ◎ | ✅ | 空输入文件→正常结束、0条输出、件数消息000000000 |
| COM-A003 | 部分0件 | 部分文件为空 | 正常结束 | ◎ | ✅ | 多输入文件时部分为空→正常结束 |
| COM-A004 | 记录长度不一致 | LRECL不匹配 | ABEND/STATUS错误 | ◎ | ⚠️ | 行式读取无LRECL强制:超长→按PIC长度substring截断;不足→padRight补齐;须确认与原程序转换语义一致 |
| COM-A005 | 磁盘满 | 容量不足 | 顺序文件STATUS 34 | ○ | | PrintWriter吞IOExceptionJ7),磁盘满无法检测。原则上不实施 |
| COM-A006 | OPEN模式违反 | 只读文件WRITE | STATUS 37 | ◎ | | Java编译期/读写模式保证,结构上不可能发生 |
| COM-A007 | 再OPEN | OPEN中再OPEN | STATUS 41 | ◎ | | openFiles()仅一处调用,代码审查确认 |
| COM-A008 | 异常结束码 | Uxxxx确认 | 与期望一致 | ◎ | ✅ | ERRORLEVEL=231exit(999))+ ABEND CODE消息确认 |
---
## 五、确认项通用基准(对应2.1.3)
| 编号 | 确认项 | 确认内容 | 优先级 | 适用 | 确认方法 |
|---|---|---|---|---|---|
| COM-C001 | 程序开始 | 程序名/日時/版本 | ◎ | ✅ | 日志确认 MSG[001] 开始消息 P5=程序ID |
| COM-C002 | OPEN确认 | 各文件OPEN正常 | ◎ | ⚠️ | 无显式OPEN日志;通过正常读取间接确认(或OPEN失败异常) |
| COM-C003 | 输入件数 | READ件数 | ◎ | ✅ | MSG[006] 9位件数 vs 输入文件行数(PowerShell `(Get-Content file).Count`;注意含空行记录) |
| COM-C004 | 输出件数 | WRITE件数 | ◎ | ✅ | MSG[007]×2 vs 输出文件行数(同上方法;空行也计入) |
| COM-C005 | 正常结束 | RETURN-CODE=0 | ◎ | ✅ | ERRORLEVEL=0 MSG[002] 终了消息 |
| COM-C006 | 异常结束 | 错误码输出 | ◎ | ✅ | ERRORLEVEL≠0 ABEND CODE消息 |
| COM-C007 | 处理时间 | 作业经过时间 | ◎ | ⚠️ | 可选:日志时刻差 / java启动~退出时刻差 |
| COM-C008 | SYSOUT | 报表输出确认 | ◎ | ✅ | 控制台输出本身(stdout重定向日志) |
---
## 六、类型别基准(对应2.2
### 6.1 条件分支系测试(IF / EVALUATE
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| B-N001 | 正常 | IF 2路分支(ELSE) | IF条件成立/不成立各处理 | ◎ | ✅ | isStatusActive()/isStatusCancel()成立/不成立两侧各走一组数据 |
| B-N002 | 正常 | IF 3路分支(ELSE IF | ELSE IF链式分支 | ◎ | ✅ | majPara()中 fieldCount≠8 / ltFound≠1 / status判定三级链,各走一组 |
| B-N003 | 正常 | IF 复合条件 AND/OR | 多个条件组合 | ◎ | ✅ | validatePara()中 sDate≠0 AND eDate≠0 AND sTime≠0 及 sDate>eDate||...复合(Q5已改CSV项目) |
| B-N004 | 正常 | IF 88-level条件名 | 88条件直接判断 | ◎ | ✅ | isStatusActive()/isStatusCancel()两侧各走一组 |
| B-N005 | 正常 | IF 嵌套3层 | 内部IF引用外部IF变量 | ◎ | ✅ | majPara() → if/else if/else 嵌套3层已实现 |
| B-N006 | 正常 | EVALUATE WHEN 多值 | 多个WHEN分支 | ◎ | ✅ | errorPara() switch(wrkErrType)case F/L/S/default 四分支 |
| B-N007 | 正常 | EVALUATE ALSO | 多条件组合判断 | ◎ | ⚠️ | 本程序未出现。复活条件:出现多条件组合判定 |
| B-N008 | 正常 | EVALUATE TRUE/FALSE | 条件表达式判定 | ◎ | ⚠️ | 本程序未出现。复活条件:出现EVALUATE WHEN条件表达式时 |
| B-N009 | 正常 | EVALUATE WHEN OTHER | 默认分支覆盖 | ◎ | ✅ | errorPara() switch的default分支 |
| B-N010 | 正常 | CONTINUE / NEXT SENTENCE | 空分支处理 | ○ | ✅ | Java→continue/空块(代码审查确认无遗漏) |
| B-A001 | 异常 | IF未闭合(缺少END-IF) | 编译错误 | ◎ | ✅ | javac保证语法正确(编译期自动) |
| B-A002 | 异常 | EVALUATE无WHEN OTHER | 全不匹配→无操作 | ○ | ⚠️ | 代码审查确认各switch均有default/完整case覆盖 |
| B-R001 | 确认 | COBOL 85条件表达式 | 关系运算符全部覆盖 | ◎ | ✅ | 逐条核对每个判定中的 = / != / > / >= / < / <= 均有测试数据覆盖 |
### 6.2 内部表检索测试(SEARCH / SEARCH ALL
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| T-N001 | 正常 | SEARCH ALL 等值查找(找到) | KEY等于目标存在 | ◎ | ➖ | 复活条件:出现SEARCH ALL(二分检索) |
| T-N002 | 正常 | SEARCH ALL 等值查找(未找到) | KEY等于目标不存在 | ◎ | ➖ | 同上 |
| T-N003 | 正常 | SEARCH ALL 多键查找 | 主键+副键组合 | ◎ | ➖ | 同上 |
| T-N004 | 正常 | SEARCH 顺序查找 | KEY条件不唯一用SEARCH | ○ | ✅ | leavserPara() for循环+break,找到/未找到各一组 |
| T-N005 | 正常 | OCCURS 1件表 | 表只有1条时检索 | ◎ | ⚠️ | 复活条件:出现OCCURS DEPENDING ON或固定表边界测试 |
| T-N006 | 正常 | OCCURS DEPENDING ON | 可变长表边界检索 | ◎ | ⚠️ | 复活条件:出现OCCURS DEPENDING ON |
| T-N007 | 正常 | INDEXED BY索引操作 | SET/SEARCH ALL 使用 INDEX | ◎ | ✅ | Java→for循环索引idx0<=idx<length边界由for结构保证 |
| T-A001 | 异常 | SEARCH ALL未排序表 | 二进制查找未排序→误命中 | ◎ | ➖ | 复活条件:出现SEARCH ALLJava→Arrays.sort必须先排序 |
| T-A002 | 异常 | INDEX越界 | OCCURS范围外访问 | ◎ | ✅ | Java数组for边界防越界;或ArrayIndexOutOfBoundsException≈ABEND |
| T-A003 | 异常 | OCCURS DEPENDING ON = 0 | 空表检索 | ◎ | ✅ | 数组length=0时循环0次→正常无操作 |
| T-R001 | 确认 | SEARCH ALL后INDEX位置 | 找到后INDEX指向正确位置 | ◎ | ✅ | break时idx值即命中位置,验证正确性 |
### 6.3 子程序调用测试(CALL / LINKAGE
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| C-N001 | 正常 | CALL字面量名 | CALL 'SUBPGM' USING ... | ◎ | ✅ | XxxSub.execute(xxxPar)——每子程序各走一组 |
| C-N002 | 正常 | CALL USING参数传递 | CALL侧+LINKAGE侧参数对应 | ◎ | ✅ | 連絡領域DTO字段set→execute→get 逐字段比对 |
| C-N003 | 正常 | CALL变量名(动态CALL | CALL WS-PGM-NAME USING ... | ◎ | | 复活条件:出现动态CALL(可用Map<String,Callable>或反射) |
| C-N004 | 正常 | CALL+RETURN-CODE | RETURN-CODE设置和检查 | ◎ | ✅ | 子程序执行后检查DTO返回码字段(getC01ChkRrc/getD01FkiCod等) |
| C-N005 | 正常 | CALL+EXIT PROGRAM | 子程序正常返回 | ◎ | ✅ | execute()方法正常return |
| C-N006 | 正常 | CALL+GOBACK | GOBACK返回(含RETURN-CODE | ◎ | ✅ | 同上(Java无GOBACK概念,方法return即可) |
| C-N007 | 正常 | IS INITIAL指定程序 | 每次CALL时WS初始化确认 | ◎ | ✅ | 调用前reset()确认(各main段均有reset |
| C-N008 | 正常 | 非IS INITIAL程序 | CALL跨调用WS值保持 | ◎ | ✅ | 子程序static无状态时N/A;有WS字段时字段保持确认 |
| C-N009 | 正常 | CALL多层嵌套(A→B→C) | 3层CALL传递参数 | ○ | ✅ | KIN01INP→SUB04CHK两层已验证;更深层出现时追加 |
| C-A001 | 异常 | CALL不存在的程序 | 未加载→ABEND | ◎ | ✅ | Java→编译错(javac保证类存在);等价确认 |
| C-A002 | 异常 | CALL USING参数长度不匹配 | CALL侧与LINKAGE侧长度不同 | ◎ | ✅ | DTO类型编译期保证;字段长度在DTO中padRight固定 |
| C-A003 | 异常 | CALL CANCEL后再CALL | CANCEL→INITIAL状态 | ◎ | ⚠️ | 本程序未出现。复活条件:出现子程序复用场景 |
| C-A004 | 异常 | CALL递归调用自身 | 需RECURSIVE编译选项 | ○ | ➖ | 复活条件:出现递归调用需求 |
| C-R001 | 确认 | CALL前STOP RUN | CALL前正常结束 | ◎ | ✅ | termPara()正常返回→main结束→exit(0) |
| C-R002 | 确认 | CALL后RETURN-CODE检查 | 子程序的返回码正确传递 | ◎ | ✅ | SUB01DAT的getD01FkiCod、SUB04CHK的getC01ChkRrc均检查 |
### 6.4 校验测试(SUB04CHK类)
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| VF-N001 | 正常 | 字段校验通过 | 输入值在允许范围内→正常输出 | ◎ | ✅ | 有効申请5项检查全通过→W01输出 |
| VF-N002 | 正常 | 字段校验拒绝 | 输入值异常→错误输出文件 | ◎ | ✅ | EMP-ID/START-DATE/START-TIME/END-DATE/END-TIME各NG→W02 ERROR-LOG |
| VF-N003 | 正常 | 重复检测(正常) | 首次出现该键→通过 | ◎ | ⚠️ | 本程序无重复检测(无排序键比较逻辑) |
| VF-N004 | 正常 | 重复检测(重复) | 同一键第二次出现→错误输出 | ◎ | ⚠️ | 同上 |
| VF-N005 | 正常 | 半角长度20桁 | 半角20桁以内→通过 | ◎ | ✅ | padRight固定长字段宽度=半角桁数,已实现 |
| VF-N006 | 正常 | 半角长度4桁 | 半角4桁以内→通过 | ◎ | ✅ | 同上 |
| VF-A001 | 异常 | 半角超长(21桁) | 半角21桁→截断/错误 | ◎ | ✅ | 须确认超长输入时截断/报错语义(padRight不截断——代码审查确认转换语义) |
| VF-A002 | 异常 | 全角混入 | 半角字段全角文字进入PIC X(半角)域 | ◎ | ✅ | 结合J4(字符vs字节差异):全角占2-3字节,定长记录字节数超长;须明确原程序转换语义 |
| VF-R001 | 确认 | 错误件数计数 | 正常件+错误件=输入件数 | ◎ | ✅ | 输入7件=W01输出3件+W02输出4件;全用例均满足 |
### 6.5 CSV→FB转换测试(无换行 / 有换行)
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| CF-N001 | 正常 | 无换行(STRING合并) | 多项目合1记录 | ◎ | ✅ | toRecordLine()输出80B定长(Kin01Rec/Kin05Rec |
| CF-N002 | 正常 | 有换行(改行展开) | 1行入力→多行出力 | ◎ | ⚠️ | 复活条件:出现含改行展开的CSV转换程序 |
| CF-N003 | 正常 | 项目内逗号/引号 | 分隔符处理 | ◎ | ⚠️ | UNSTRING不识别引号;Java split同样不识别=忠实等价;须确认原程序式样 |
| CF-N004 | 正常 | 引号内字符串 | "..."内逗号/改行保持 | ◎ | ⚠️ | 同上(若原程序支持引号解析,须在转换规则中单独实现) |
| CF-N005 | 正常 | 空项目连续逗号 | 空字符串处理 | ◎ | ✅ | split(",",-1)保持尾部空串(UNSTRING TALLYING语义) |
| CF-N006 | 正常 | 全项目最大长 | 各项目到PIC定义上限 | ◎ | ✅ | padRight补齐最大宽度,字符串长度不超过PIC(n) |
| CF-A001 | 异常 | 改行位置超记录长 | 改行展开后1行超定义长 | ◎ | ✅ | padRight截断/补位语义与COBOL一致(String=n char天然保持) |
| CF-A002 | 异常 | 引号未闭合 | 剩余全部为1项目 | ◎ | ⚠️ | 同CF-N003/004;原程序不识别引号→忠实等价 |
### 6.6 文件编成测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| FO-N001 | 正常 | 顺次读取 | 先头→最终全件正常READ | ◎ | ✅ | BufferedReader.readLine() 逐行读至null |
| FO-N005 | 正常 | LINE SEQUENTIAL读取 | 改行区切り文本文件READ | ◎ | ✅ | 同上(Java文本文件即LINE SEQUENTIAL |
| FO-N002~004 | 正常 | VSAMKSDS/RRDS | 索引文件/相对文件 | ◎ | ➖ | 复活条件:出现索引/相对文件需求 |
| FO-A001~004 | 异常 | VSAM异常 | OPEN/READ/WRITE异常 | ◎ | | 复活条件:出现VSAM文件 |
| FO-R001 | 确认 | FILE STATUS确认 | 各I/O后STATUS值 | ◎ | ⚠️ | Java无FILE STATUS;通过异常机制等价:IOException/UncheckedIOException |
### 6.7 数值精度补充说明
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| NP-N001 | 正常 | COMP-3小数位对齐 | PIC S9(7)V99与S9(9)V9的ADD对齐 | ◎ | ✅ | COMP-3→long整数运算;有小数时→BigDecimal |
| NP-N002 | 正常 | ROUNDED选项 | 计算结果四舍五入到指定小数位 | ◎ | ✅ | setScale(..., RoundingMode.HALF_UP) 一致性确认 |
| NP-N003 | 正常 | ON SIZE ERROR | 结果超过PIC定义域时触发 | ◎ | ⚠️ | J6Java无自动SIZE ERROR;转换时须显式实现(throw/标记);必查实现存在性 |
| NP-N004 | 正常 | 除算余数(REMAINDER | DIVIDE...REMAINDER | ◎ | ⚠️ | 复活条件:出现DIVIDE REMAINDERJava→BigInteger.remainder() |
| NP-N005 | 正常 | COMP(二进制)符号处理 | S9(4) COMP的符号位正确 | ◎ | ✅ | int/long天然有符号(补码) |
| NP-N006 | 正常 | COMPUTE中间精度 | 中间结果精度确保最终结果正确 | ◎ | ✅ | BigDecimal运算顺序注意(scale/precision |
| NP-N007 | 正常 | 符号付/符号なし混算 | S9(5)与9(5)的ADD/SUBTRACT | ○ | ⚠️ | Java无符号short/byte→全部用int/long(补码),混算语义与COBOL不完全等价;须按转换规则实现 |
| NP-A001 | 异常 | 超过PIC定义域(无SIZE ERROR) | 高位截断→数据错误 | ◎ | ✅ | padLeftZero位数语义与COBOL一致(9位零填充等) |
| NP-A002 | 异常 | COMP-3符号误判 | 符号nibble('C'/'D')不一致 | ◎ | | Java无pack/unpack自写代码(ConvUtil统一转换,无nibble操作) |
| NP-A003 | 异常 | 除算0除 | DIVIDE BY ZERO→ABEND | ◎ | ✅ | ArithmeticException≈ABEND;须在转换中显式捕获或检查除数 |
| NP-A004 | 异常 | COMP赋值溢出 | 超范围数值MOVE到COMP字段 | ◎ | ⚠️ | J5int溢出静默绕回≠COBOL截断;必测溢出用例 |
| NP-R001 | 确认 | 演算结果精度一致 | 同一演算反复执行→结果一致 | ◎ | ✅ | 多次运行同一用例输出一致(幂等性+无随机因素) |
| NP-R002 | 确认 | 小数点位置一致 | 编辑字段十进制位正确 | ◎ | ✅ | padLeftZero / 编辑输出字段的小数点位置与COBOL一致 |
### 6.8 循环处理测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| LP-N001 | 正常 | PERFORM VARYING(计数循环) | VARYING I FROM 1 BY 1 UNTIL I > N | ◎ | ✅ | Java→for循环 |
| LP-N002 | 正常 | PERFORM UNTIL(条件循环) | 条件达到后退出 | ◎ | ✅ | Java→while |
| LP-N003 | 正常 | PERFORM TIMES(固定次数) | N回执行 | ◎ | ✅ | Java→for(0..N) |
| LP-N004 | 正常 | PERFORM THRU(段落跨入) | THRU指定多个段落 | ○ | ✅ | Java→顺序方法调用(重构方针下THRU已拆分) |
| LP-N005 | 正常 | 内联PERFORMEND-PERFORM | COBOL85内联循环 | ◎ | ✅ | Java→while/for |
| LP-N006 | 正常 | 嵌套PERFORM3层) | 内层PERFORM完整执行后外层继续 | ◎ | ✅ | Java→嵌套for/while(检查嵌套≤3层) |
| LP-N007 | 正常 | EXIT PERFORM / EXIT PERFORM CYCLE | 中途退出/跳过本次循环 | ◎ | ✅ | Java→break/continue |
| LP-A001 | 异常 | PERFORM VARYING 0回 | 初始值已超终值→0回执行 | ◎ | ✅ | Java→for条件初值已超终值→循环0次 |
| LP-A002 | 异常 | 无限循环(条件永不满足) | UNTIL条件永不成立→超时 | ○ | ⚠️ | Java→while(true)无退出时;超时观察○(本程序无此风险) |
| LP-A003 | 异常 | PERFORM嵌套越界 | 内层PERFORM THRU跨入外层段落 | ◎ | ➖ | 重构方针下不存在(方法拆分隔离) |
| LP-A004 | 异常 | EXIT SECTION/GOBACK误用 | 循环内意外退出程序 | ◎ | ➖ | Java无SECTION概念;方法return不会意外退出主程序 |
| LP-R001 | 确认 | 循环回数确认 | 实际执行回数与期望一致 | ◎ | ✅ | 计数器(cunR01Inn等)/ 日志确认;或循环中加临时计数器验证 |
### 6.9 日期处理测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| D-N001 | 正常 | 通常日期(YYYYMMDD) | 正常日期处理 | ◎ | ✅ | Java→int/String YYYYMMDDSUB04CHK DATE检查 |
| D-N002 | 正常 | 闰年判定 | 2000/2004/2100年 | ◎ | ✅ | SUB04CHK DATE内含闰年判定逻辑 |
| D-N003 | 正常 | 月末日 | 1月31日/2月28日/2月29日 | ◎ | ✅ | 同上(SUB04CHK DATE |
| D-N004 | 正常 | 日期计算(±日) | FUNCTION INTEGER-OF-DATE | ◎ | ⚠️ | 复活条件:出现日期加减计算 |
| D-N005 | 正常 | 日期比较 | 日期前后比较 | ○ | ✅ | validatePara() sDate>eDate 已比较;各种比较语义确认 |
| D-A001 | 异常 | 日期逻辑异常 | 2月30日/4月31日 | ◎ | ✅ | 测试数据开始月=13等异常日期→ERROR(已测:KIN01R01.csv #6 |
| D-A002 | 异常 | 西历/和历混在 | YYYYMMDD与RYYMMDD混用 | ◎ | | 本工程统一YYYYMMDD;复活条件:出现和历处理程序 |
| D-A003 | 异常 | 2桁年(YYMMDD | 2000年区分问题 | ◎ | ➖ | 本工程统一4桁年;复活条件:出现2桁年处理 |
---
## 七、不适用类别清单(当前未出现,出现时按原基准全面启用)
| 类别编号 | 类别 | 复活条件(该类型程序出现时) | 主要测试项摘要 |
|---|---|---|---|
| MT-* | 匹配基础测试 | 出现匹配处理程序(主从件键对应) | MT-N001~006正常+异常、MT-R001匹配件数合计 |
| SY-* | SYSIN读取测试 | 出现批处理参数读取(main(args)/系统属性) | SY-N001~003正常、SY-A001~003异常 |
| S-* | 分割系测试 | 出现文件分割程序 | S-N001~007正常(50/25/100分割)、S-R001~002确认 |
| KB-* | key切测试 | 出现汇总/聚合/中断处理程序 | KB-N001~006正常、KB-A001~002异常 |
| SR-* | SORT类型测试 | 出现排序处理(Arrays.sort+Comparator | SR-N001~008正常(升序/降序/多键/INPUT PROCEDURE)、SR-A001~003异常 |
| MR-* | MERGE类型测试 | 出现多文件合并 | MR-N001~003正常、MR-A001异常 |
| ED-* | 编辑输出测试 | 出现报表类程序(改行/改页/编辑字段) | ED-N001~005正常、ED-A001~002异常、ED-R001行数合计 |
| AE-* | ASCII↔EBCDIC编码转换 | 出现编码转换需求(本工程统一UTF-8 | AE-N001~003正常、AE-A001~003异常、AE-R001转换后长度 |
| OL-* | online/CICS测试 | 出现在线处理程序(DFHCOMMAREA/MAP | OL-N001~004正常、OL-A001~003异常、OL-R001响应时间 |
| DB-* | DB操作/检索/SELECT条件 | 出现DB处理程序(已备DbSample模式) | DB-N001~006正常、DB-A001~003异常、DB-R001 SQLCODE |
| AM-* | 高级匹配测试 | 出现多段匹配/混合处理程序 | AM-N001~008正常、AM-A001~002异常、AM-R001各段件数 |
---
## 八、横跨功能测试基准(对应2.3)
### 8.1 可变长入出力
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| VL-N003 | 正常 | LINE SEQUENTIAL文件读写 | 行可变长文件(LF结尾)逐行READ | ◎ | ✅ | BufferedReader.readLine() 逐行读 |
| VL-N005 | 正常 | 可变长→固定长转换 | 可变长记录READ到固定长记录域 | ◎ | ✅ | CSV行→80B定长记录(toRecordLine |
| VL-N001~004 | 正常 | RECORD IS VARYING | 可变长记录直接读写 | ◎ | ⚠️ | 复活条件:出现COBOL RECORD VARYINGJava无此概念;按行式文本文件等价处理) |
| VL-N006 | 正常 | RECORD VARYING FROM 1 TO 99 | 最小~最大件数之间的任意长度 | ◎ | ⚠️ | 同上 |
| VL-A001~004 | 异常 | ODO/VARYING异常 | 超限/截断/STATUS 47 | ◎ | | 复活条件:出现OCCURS DEPENDING ON |
| VL-R001 | 确认 | RECORD LENGTH确认 | WRITE后文件LRECL与定义一致 | ◎ | ✅ | 输出行字节数检查(80B定长 + 换行符) |
### 8.2 数值精度
见6.9NP-*系列详细表)
### 8.3 日文文字处理
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| J-K004 | 异常 | 全角/半角混用 | 混用数据处理 | ◎ | ✅ | 结合J4:全角占2-3字节,定长记录字节数超长;须明确转换语义 |
| J-S001 | 正常 | 全角空格TRIM | TRIM对全角空格 | ◎ | ⚠️ | Java trim()仅去半角空格;全角空格须正则替换(转换规则决定) |
| J-D001~004 | 正常 | Shift-JIS 5C/7C | 特殊字节处理 | ◎ | | 本工程统一UTF-8无SJIS处理 |
| J-X系列 | 正常/异常 | EBCDIC↔SJIS转换 | 编码转换 | ◎ | | 本工程统一UTF-8 |
| J-N/G/S系列 | 正常/异常 | PIC N/外字/全角空格 | 全角字段/外字/编辑 | ◎ | ➖ | 复活条件:出现PIC N字段或外字需求 |
### 8.4 RERUN / RESTART 测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| RR-N001 | 正常 | 同一数据再执行 | 幂等性确认(不重复更新) | ◎ | ✅ | 同一输入再执行一次,输出文件完全一致(J8:覆盖模式) |
| RR-A001 | 异常 | 输出文件未删除 | 再执行STATUS 95 | ◎ | ⚠️ | Java→FileOutputStream覆盖=正常结束(与主机STATUS95差异已记录;须确认转换规则) |
| RR-A002 | 异常 | 中间ABEND→RESTART | 中间状态重新开始 | ◎ | ➖ | 复活条件:出现检查点/重启机制需求 |
| RR-A003 | 异常 | ABEND时输出文件状态 | 中途废弃/部分输出 | ◎ | ⚠️ | Java→ABEND后已输出行保留(未close时flush未保证);测试确认部分输出行为 |
### 8.5 排他/竞争测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| EX-N001 | 正常 | 同时READ | 多个JOB同时READ | ◎ | ➖ | 单进程批处理对象外;复活条件:出现多实例并发需求 |
| EX-A001~003 | 异常 | WRITE冲突/DELETE | STATUS 48/95/97 | ◎ | | 同上 |
### 8.6 性能/容量测试
| 编号 | 区分 | 项目 | 内容 | 优先级 | 适用 | Java确认方法 |
|---|---|---|---|---|---|---|
| PV-N001 | 正常 | 10万件处理 | 批量处理性能 | ○ | ✅ | 生成脚本造10万条CSV,记录处理时间(time命令) |
| PV-A001 | 异常 | SORT区不足 | RC=20 | ○ | | 复活条件:出现SORT程序 |
---
## 九、测试计划制定方法(每轮固定手顺)
1. **确定该程序类型**:文件处理/匹配/分割/SORT/DB等,按第六节选对应类别
2. **选必测底座**:第三节~第五节的◎项 = 每轮必测(COM-N001/002/004/005/006/008COM-A001/002/004/008COM-C001/003/004/005/008
3. **选类型别适用项**:第六节按程序类型勾选适用行(✅必测,⚠️确认等价,➖跳过并注明)
4. **选横跨适用项**:第八节勾选适用行
5. **派生数据用例**:每个基准项派生具体输入数据+期望输出,形成测试计划表
6. **执行**:按第二节手顺运行
7. **记录**:结果记入对照表《验证结果》
### 测试计划表模板
| 用例ID | 基准编号 | 目的 | 输入数据 | 期望结果 | 实际结果 | 结果 |
|---|---|---|---|---|---|---|
| TC001 | COM-N001 | 最小数据1条 | 1条正常记录 | W01输出1件,内容一致 | | OK/NG |
| TC002 | COM-A001 | 文件不存在 | 删除R01输入文件 | 异常+退出码≠0 | | OK/NG |
| ... | ... | ... | ... | ... | | |
---
## 附录:与COBOL测试基准的ID映射速查
| COBOL原ID | Java对应ID | 说明 |
|---|---|---|
| COM-N001~008 | COM-N001~008 | 通用正常系(全保留,按适用性筛选) |
| COM-A001~008 | COM-A001~008 | 通用异常系(部分降级为等价行为) |
| COM-C001~008 | COM-C001~008 | 通用确认项(SYSOUT→stdout |
| B-N/A/R | B-N/A/R | 条件分支(全保留) |
| T-N/A/R | T-N/A/R | 内部表检索(保留适用项) |
| C-N/A/R | C-N/A/R | 子程序调用(保留适用项) |
| VF-N/A/R | VF-N/A/R | 校验测试(保留适用项) |
| CF-N/A/R | CF-N/A/R | CSV转换(保留适用项) |
| FO-N/A/R | FO-N/A/R | 文件编成(仅LS适用) |
| LP-N/A/R | LP-N/A/R | 循环处理(全保留) |
| NP-N/A/R | NP-N/A/R | 数值精度(保留适用项) |
| D-N/A | D-N/A | 日期处理(保留适用项) |
| VL-N/A/R | VL-N/A/R | 可变长(LS相关项适用) |
| RR-N/A | RR-N/A | RERUN(幂等性适用) |
| PV-N | PV-N | 性能(10万件○) |
| MT/SY/S/KB/SR/MR/ED/AE/OL/DB/AM | (不适用) | 按第七节复活条件启用 |
---
**本文档基准版本**: v1.02026-08-22 作成)
**来源文档**: COBOL测试基准说明.md(程序分类及测试基准.pdf 第2部)
**适用范围**: 本项目所有COBOL→Java转换程序的步骤5验证
+165
View File
@@ -0,0 +1,165 @@
# 代码确认 Checklist(模板)
步骤6【代码确认】使用的确认模板。每轮转换时复制本文件内容到 `doc\conv\程序名_对照表.md` 中填写结果,本文件本身保持为空白基准模板。
本 Checklist 从七个维度审查:**机能正确性**、**规约符合性**、**可读性**、**保守性(维护性)**、**健壮性(异常处理)**、**性能与效率**、**安全性与可观测性**。
- **机能正确性**(一):以 `doc\design\` 详细设计书为基准,逐机能项核对实现与验证证据,并覆盖分支、边界、精度、异常路径。
- **规约符合性**(二):按转换规则的映射条目逐条检查。
- **可读性 / 保守性**(三 / 四):在**不破坏与 COBOL 的 1:1 对应关系**这一前提下检查;凡与忠实转换原则冲突时,以忠实转换为优先并记录理由。
- **健壮性(五)**:异常路径、边界、资源安全、ABEND 一致性——批量程序须保证任何单笔异常不泄露为进程崩溃且资源不泄漏。
- **性能与效率(六)**:IO/转换开销、不必要对象创建、批量规模下的稳定性。
- **安全性与可观测性(七)**:日志内容恰当、无敏感信息泄露、权限与编码等运行前提明确。
任一条目 NG 时记入《不合格项记录》,修正后复检;全部通过后方可交付。
---
## 一、机能确认清单
> 机能项从详细设计书中提取,逐项标注实现位置和验证证据。
| No | 机能项(设计书出处) | 实现位置(类#方法 | 验证方式 | 结果 |
|---|---|---|---|---|
| 1 | (例:1.1 日次取込处理) | Sampl01Main#initPara | 测试数据运行比对 | OK/NG |
| 2 | | | | |
### 正确性验证要点
> 机能项清单验证"实现了没有",本节验证"实现得对不对、全不全"。逐条打勾,NG 记入不合格项。
- [ ] 分支覆盖:设计书描述的每个判定条件至少有 1 组测试数据走过真/假两侧;COBOL 原程序的各 IF/EVALUATE 分支在 Java 中均有对应且条件等价
- [ ] 边界值:空输入 / 最大长度 / 最小值·最大值 / 0 除 / 文件末尾记录 等边界已验证
- [ ] 计算精度:金额类 BigDecimal 的 scale 与 ROUNDED 舍入模式与原程序一致
- [ ] 异常路径等价:文件不存在、记录格式错、DB 访问失败等异常时,消息内容与 ABEND 行为(退出码)与原程序/设计书一致
- [ ] 输出件数与内容:输出文件件数、汇总值、消息编号与设计书预期一致(不只看"能跑通")
- [ ] COBOL→Java 差异等价性:REDEFINES 多视图写入方式与原 COBOL 一致(整区覆写 vs 单视图写入);INITIALIZE 后 String 非 nullMOVE 定长化与原程序一致;参考修正起始位置正确
## 二、规范确认清单
### 1. 命名规范(对应规则 3.1)
- [ ] 类名 = PROGRAM-ID 驼峰化 + Main/Sub 后缀
- [ ] `WS-XXX``wsXxx` 字段,无遗漏、无改名
- [ ] 段落 `XXX-PARA``xxxPara()` 方法一一对应
- [ ] VALUE 常量 → `CST_XXX`88 级 → 常量 + `isXxx()` 判定方法
- [ ] COPY 句 → `dto\` 下 DTO 类
- [ ] 文件 SELECT ASSIGN → `INP_FILE` / `OUT_FILE` 路径常量
### 2. 类型映射(对应规则 3.2)
- [ ] PIC X(n) → StringPIC 9(n) → int/longPIC 9(n)V99 → BigDecimal
- [ ] ROUNDED → setScale(…, RoundingMode.HALF_UP)
- [ ] 固定长记录 substring 的起止位置与 05 层定义一致,且有位置注释
- [ ] PIC 转换统一调用 util.ConvUtil,无散落自写转换逻辑
### 3. 结构映射(对应规则 3.3 / 3.4)
- [ ] WORKING-STORAGE → 私有字段区;段落 → private 方法
- [ ] PERFORM UNTIL → whilePERFORM VARYING → forTHRU → 顺序方法调用
- [ ] IF/ELSE → if/elseEVALUATE(含 WHEN OTHER)→ switch/default
- [ ] GO TO 处理符合方针:保持原结构,仅冗长时小范围重构(已记录)
- [ ] CALL 子程序 → 独立类方法调用,参数传递与原程序一致
- [ ] OCCURS / DEPENDING ON / REDEFINES / COMP-3 按规则处理
- [ ] 字段为 instance(每轮 new 新实例),非 static(子程序 static execute 方法内无状态字段例外)
### 4. 文件处理
- [ ] OPEN/CLOSE:同段落内用 try-with-resources;跨段落(OPEN在初期处理、CLOSE在终了处理)时用字段保持+显式 close 模式
- [ ] READ AT END → readLine() == nullREAD 循环逻辑与原程序一致
- [ ] WRITE 输出格式(定长化/编辑)与原程序报表格式一致
- [ ] 文件编码明确(默认 UTF-8,原文件为其他代码页时已注明)
- [ ] 非 try-with-resources 模式时,closeFiles() 在所有路径(正常+异常)均被调用,无资源泄漏
### 5. DB 处理
- [ ] EXEC SQL → PreparedStatement,宿主变量 → setXxx 一一对应
- [ ] 游标 DECLARE/OPEN/FETCH/CLOSE → executeQuery()/rs.next()/自动关闭
- [ ] COMMIT / ROLLBACK 时机与原程序一致
- [ ] WHENEVER SQLERROR → try-catch + rollback 模式
- [ ] SQL 与详细设计书/DDL 的表名列名一致
### 6. 注释与可追溯性(对应规则 3.5)
- [ ] 类头有 COBOL↔Java 整体结构对应说明
- [ ] 字段/方法标注了对应的 COBOL 数据项/段落
- [ ] 关键语句行内标注原 COBOL 语句
### 7. 通用约束(第四节)
- [ ] compile.bat 编译通过
- [ ] 源码 UTF-8;纯 JDK8,未引入新依赖
- [ ] 提供测试数据时已运行比对,输出一致
- [ ] 未操作项目目录以外的任何内容
- [ ] 包结构明确:无 package 语句(默认包)时确认符合预期;有 package 时目录结构一致
- [ ] run.bat 已适配本轮主类名(java -cp out 主类名)
### 8. COBOL→Java 差异确认清单(对应规则 3.7)
> COBOL 与 Java 存在系统性语义差异,转换时须逐项确认等价性。详见 `doc\转换基准.md` 3.7 节。
- [ ] **INITIALIZE 等价性**String 字段显式初始化为 `""`(非 null);数值字段默认 0 或显式赋 0;setter 方法有 null 防护(`(v == null) ? "" : v`);reset() 与 COBOL INITIALIZE 逐项对应
- [ ] **REDEFINES 视图一致性**:reset() 清零主存储(等价 INITIALIZE 整区内存归零);单视图写入(MOVE 分组项)与 COBOL 语义一致(仅修改对应位);整区覆写(MOVE 整个 REDEFINES 项)须同时写入所有视图(确认原 COBOL 的 MOVE 目标)
- [ ] **MOVE 定长化**String 字段用 `ConvUtil.padRight` / `padLeftZero` 显式定长,不依赖 Java 自动处理;定长记录的 substring 位置与 05 层定义一致且有注释
- [ ] **参考修正起始位置**COBOL 参考修正 `X(1:1)` 起始位置为 1Java `substring(0, 1)` 起始位置为 0。确认原 COBOL 是否使用参考修正,Java 实现是否正确偏移
- [ ] **UNSTRING 字段数判定**COBOL TALLYING 统计分隔符个数(8字段=7分隔符);Java `split(-1).length` 返回字段个数(=8)。判定逻辑须等价(`cnt+1 == length`),不可直接等同
- [ ] **REDEFINES 整区覆写确认**:检查原 COBOL 的 MOVE 目标是整个 REDEFINES 项(如 WRK-DEMO-AREA)还是某个分组项(如 WRK-DEMO-TYPE)。整区覆写→Java 须同时 set 所有视图;单视图写入→Java 仅 set 对应视图
## 三、可读性确认清单
> 前提:不破坏与 COBOL 的 1:1 对应关系。凡为可读性而做的改动(如方法拆分、变量别名)必须已记录在对照表《差异》节中。
- [ ] 方法长度适当:单个段落方法过长时(目安 >80 行),已在保持段落对应的前提下拆出私有辅助方法,且拆分点有注释说明
- [ ] 命名自明:字段/方法名见名知义;与 COBOL 名差异大的(如缩写)在注释中标注了原文名
- [ ] 无魔数:字面量 0/1 以外的判定值、固定长位置均使用 CST_ 常量或带注释
- [ ] 无死代码:无被注释掉的大段代码、无不可达分支;转换过程中的临时调试代码已清除
- [ ] 嵌套深度:if/for 嵌套不超过 3 层;超出的已用早退(return/continue)或条件提取改善,且不改变判定语义
- [ ] 注释质量:类头/段落头注释能让人不看 COBOL 也理解该块做什么;无“翻译腔”逐行废话注释
## 四、保守性(维护性)确认清单
> 前提同上。本节检查后续维护者改错、改规格时的难易度。
- [ ] 共通逻辑收敛:PIC 转换、定长拆分、消息输出等重复逻辑统一走 util / 子程序类,无复制粘贴副本(改一处即可全生效)
- [ ] 职责单一:主程序不直接做文件格式细节,细节收敛在 DTO / util 中
- [ ] 复用性:子程序入口签名统一 execute(par),連絡領域 DTO 可被其他程序复用
- [ ] 变更影响面小:字段追加/条件变更时只需改一处定义(DTO 或常量区),不需散改多处 substring 位置
- [ ] 异常处理方针一致:所有 ABEND 场景使用同一模式(消息 + 统一退出码),新增维护代码可照抄现有写法
- [ ] 与标准例一致性:结构、命名、异常处理写法与本工程 `src\Sample01Main.java` 等标准例风格一致,维护者可举一反三
## 五、健壮性(异常处理·边界·资源安全)确认清单
> 批量/文件处理程序的核心质量属性。任何单笔数据异常不应导致进程崩溃或资源泄漏;所有异常路径的消息与退出码须与原程序/设计书一致。
- [ ] 单笔异常隔离:单条记录格式错/校验错/解析异常被捕获并按设计书输出 ERROR-LOG,不中断整批处理(除非设计书要求 ABEND)
- [ ] 异常路径等价:文件不存在、记录格式错、DB 访问失败等时,消息内容与 ABEND 行为(退出码)与原程序/设计书一致
- [ ] 资源安全:所有 I/O 流在正常与异常路径均关闭(try-with-resources 或 closeFiles 全覆盖),无句柄泄漏
- [ ] 数值/格式安全:Integer.parseInt 等解析对空/非数字输入有防护或已在更前置的校验拦截(不产生未捕获异常)
- [ ] 边界值:空输入 / 最大长度 / 0 值 / 文件末尾记录 等边界已验证
- [ ] ABEND 一致性:所有 ABEND 场景统一走 消息+退出码 模式,退出码(含 Windows 取模后实值)与设计书一致
## 六、性能与效率确认清单
> COBOL 批处理转换后须保持同等规模下的可接受性能与稳定性。
- [ ] IO 效率:逐行读写、无整文件无谓加载;大文件场景下内存占用平稳
- [ ] 转换开销:PIC/定长处理复用 util.ConvUtil,无重复创建大对象或正则等重操作
- [ ] 不必要输出:无调试用 System.out/print 遗留;消息输出符合设计书
- [ ] 循环与批量:READ 循环/段落调用结构与 COBOL 等价,无额外嵌套或重复计算
- [ ] 资源复用:DTO/缓冲在同一实例内复用,无每笔 new 大对象的不必要开销
## 七、安全性与可观测性确认清单
> 日志与运行前提的可控、可排查。
- [ ] 日志恰当:消息编号/参数与设计书一致,运维可据此定位;无暴露内部栈或敏感数据
- [ ] 无敏感信息泄露:输出/日志不含密码、密钥、个人敏感字段的超范围暴露
- [ ] 编码明确:源码 UTF-8;输入/输出文件编码在设计书或对照表中注明
- [ ] 运行前提:所需 JDK 版本、外部依赖(JDBC 驱动等)在 compile.bat/run.bat 或对照表中明确
- [ ] 权限与范围:仅操作项目目录内,未触碰系统或其他工程文件(见 README 前提事项)
## 八、不合格项记录
| No | 检查项 | 不合格内容 | 修正措施 | 复检结果 |
|---|---|---|---|---|
| 1 | | | | |
+224
View File
@@ -0,0 +1,224 @@
# COBOL→Java 转换 作业流程与规则(项目基准)
本文件为全项目转换作业的技术基准(流程+规则+环境要求)。作业前提事项(目录权限·备份规则·文件归置)见根目录 `README.md`
**核心原则:代码转换优先依据式样书(详细设计书),原 COBOL 代码仅作参考。式样书与原代码不一致时,以式样书为准(已确认的差异记入对照表《疑问·回答记录》);测试验证优先依据 `doc\Java测试基准说明.md`。**
## 一、目录约定
```
项目根\
├── README.md 项目导览·前提事项
├── compile.bat 编译脚本(javac 直调,不改系统配置)
├── run.bat 运行主示例
├── run_db.bat 运行 DB 示例
├── src\ Java 源码(主程序、子程序、DTO、工具类)
├── cobol\ COBOL 源码(主程序、COPY 句、子程序)
│ ├── copy\ COPY句成员
│ └── sub\ 子程序 COBOL 源码
├── doc\ 文档(基准文档·式样书·DDL·各轮对照表)
│ ├── design\ 式样书·详细设计书(Markdown,按程序名命名)
│ ├── db\ 表定义 DDL / 字段一览
│ ├── conv\ 每程序的《转换对照表》(Markdown)
│ ├── 转换基准.md 本文件
│ ├── 代码确认Checklist.md(步骤6使用的确认模板)
│ └── Java测试基准说明.md(测试用例编写基准)
├── data\ 测试数据、输入输出文件
│ └── test\ 测试资产(按程序名分目录)
├── lib\ JDBC 驱动 jar
├── out\ 编译输出(compile.bat 每次清空重建)
├── bk\ 备份(按日期时刻命名,详见 README 第五节)
├── tmp\ 作业临时区(可随时清空)
├── tools\ 自动化脚本(按需追加)
└── gitPushFolder\ git 推送暂存目录(复制 src\3bat 后在此 pushgit 不碰其他文件夹)
```
标准例:`Sample01Main`(常用语法映射)、`FileSample`(文件处理)、`DbSample`DB访问)、`dto\EmpRec`(记录布局)、`util\ConvUtil`PIC 转换)。转换时套用该模式。
## 二、作业流程(每个 COBOL 程序一轮)
| 步骤 | 内容 | 产出 |
|---|---|---|
| 1. 受理确认 | 核对主程序/COPY句/式样书/DDL 是否齐全 | 文件清单 |
| 2. 分析 | 通读代码+COPY+式样书,整理变量一览、段落一览、文件/SQL/CALL 一览 | 转换分析表 |
| 3. 疑问确认 | 业务逻辑不明点、代码与式样书不一致处列疑问表,用户答复后才动工 | 疑问·回答记录 |
| 4. 转换 | 按第三节规则生成 Java,套用标准例模式 | src\ 下源码 |
| 5. 验证 | ① javac 编译通过 ② COBOL↔Java 逐项核对(分支/计算/文件IO/SQL)③ 有测试数据则运行比对输出 | 核对结果 |
| 6. 代码确认 | 按 `doc\代码确认Checklist.md` 从四个维度审查:① **机能正确性**:设计书机能项逐项核对实现位置,并覆盖分支/边界/精度/异常路径;② **规约符合性**:命名/类型映射/结构/注释等逐条检查;③ **可读性**、④ **保守性(维护性)**:在不破坏 COBOL 1:1 对应关系的前提下检查(冲突时以忠实转换为优先并记录理由) | 四维度确认清单(记入对照表) |
| 7. 交付 | 源码 + `doc\conv\程序名_对照表.md` | 对照表 |
- 每轮一个程序,用户验收后再进下一个。
- 第6步先由转换方自查出清单并修正不合格项,最后由用户最终验收。
## 三、转换规则
### 3.1 命名规则
| COBOL | Java |
|---|---|
| PROGRAM-ID `SAMPL01`(主程序) | 类 `Sampl01Main`(驼峰化 + Main 后缀) |
| PROGRAM-ID `SUBPROG`(子程序) | 类 `SubprogSub`(驼峰化 + Sub 后缀) |
| `WS-XXX` 变量 | `wsXxx` 字段 |
| `XXX-PARA` 段落 | `xxxPara()` 方法(private |
| VALUE 常量 / 88 级条件名 | `CST_XXX` 常量 / `isXxx()` 判定方法 |
| COPY 句(记录用,如 KIN01REC | `dto\` 下 DTO 类,命名 `XxxRec` |
| COPY 句(連絡領域用,如 ZANCHKAC) | `dto\` 下 DTO 类,命名 `XxxPar` |
| CALL 'SUBX' USING ...PAR | `SubxSub.execute(par)`(子程序统一入口方法名 execute) |
| 文件 SELECT ASSIGN | `INP_FILE` / `OUT_FILE` 路径常量 |
### 3.2 类型规则(统一走 util.ConvUtil
| COBOL | Java |
|---|---|
| PIC X(n) | StringpadRight 定长化) |
| PIC 9(n) | int / longpadLeftZero |
| PIC 9(n)V99 | BigDecimaltoDecimal / formatZoned |
| COMPUTE … ROUNDED | setScale(…, RoundingMode.HALF_UP) |
| 固定长记录拆分 | substring(位置注释对应 05 层定义) |
### 3.3 语句·结构映射
| COBOL | Java |
|---|---|
| WORKING-STORAGE SECTION | 类私有字段区 |
| PROCEDURE DIVISION 段落 | private 方法 |
| PERFORM 段落 | 方法调用 |
| PERFORM UNTIL | while |
| PERFORM VARYING | for |
| PERFORM A THRU B | 一个方法内依次调用 aPara()…bPara() |
| IF / ELSE / END-IF | if / else |
| EVALUATE … WHEN OTHER | switch / default |
| DISPLAY | System.out.println |
| READ … AT END | readLine() == null |
| OPEN / CLOSE | 同段落→try-with-resources;跨段落→字段保持+显式 close(参照标准例 FileSample |
| WRITE | writer.println / write |
| CALL 子程序 | 子程序独立类的方法调用(参数按引用→返回值或可变对象承载) |
| EXEC SQL(游标/单行/COMMIT/ROLLBACK/WHENEVER SQLERROR | JDBC PreparedStatement / commit / rollback / try-catch(见 DbSample |
| OCCURS | 数组 / List |
| DEPENDING ON | 动态数组 / List(长度由变量决定) |
| REDEFINES | 同一数据的两种解析视图。reset()清零主存储即可(等价INITIALIZE);单视图写入与COBOL MOVE语义一致,无需同时清零其他视图。整区覆写时须同时写入所有视图(详见3.7(2)) |
| COMP-3packed | ConvUtil 扩展二进制解析方法(需要时追加) |
### 3.4 GO TO 方针
原则上原代码未使用 GO TO。若出现:**尽量保持原段落结构;仅当特别冗长时做小范围结构化重构**(段内跳过→if 包裹、跨段→方法调用/标志位)。不做 goto 机械模拟。
### 3.5 注释规则
- 类头:COBOL↔Java 整体结构对应说明。
- 字段/方法:标注对应 COBOL 数据项/段落。
- 关键语句行内:标注原 COBOL 语句(MOVE/COMPUTE/EXEC SQL 等),保证可追溯。
### 3.6 异常处理统一模式
所有程序的 ABEND 处理使用同一模式,便于维护者举一反三:
- 业务逻辑异常:`abendPara()``Sub03EndSub.execute(e01AbdPar)``System.exit(999)`Windows 退出码 231
- 文件 I/O 异常:`UncheckedIOException`JVM 默认退出码 1
- 消息输出统一走 `msgOutPara()`,不散落 System.out
### 3.7 COBOL→Java 差异点特殊处理
COBOL 与 Java 在语义上存在多处系统性差异,转换时须逐项确认等价性。以下为必须特殊考虑的差异点:
#### (1) INITIALIZE vs Java 默认值
| 项目 | COBOL | Java | 注意事项 |
|---|---|---|---|
| 数值字段 | INITIALIZE → ZERO | int/long 默认 0 | 等价,无需额外处理 |
| 字符字段 | INITIALIZE → SPACES | String 默认 **null**(非 SPACES | **必须显式初始化为 `""`**,否则后续拼接/比较会 NPE |
| setter 方法 | MOVE SPACES → 字段 | setter 须加 null 防护:`(v == null) ? "" : v` | 防止外部传入 null |
| reset() 方法 | INITIALIZE 整个记录 | 数值→0、文字→"" | 每个 DTO 须实现 reset(),与 COBOL INITIALIZE 逐项对应 |
#### (2) REDEFINES 多视图
COBOL 的 REDEFINES 表示同一内存区域的多种解析视图。写入任一视图,其他视图同时反映变化。
| 场景 | COBOL 行为 | Java 实现 | 注意事项 |
|---|---|---|---|
| reset() INITIALIZE 等价) | 整个内存区域清零,所有视图同时归零 | reset() 中清零主存储字段 | reset() 不需要逐视图清零,清零主存储即可 |
| 单视图写入(MOVE 分组项) | MOVE WRK-DEMO-TYPE → 仅写入前4位,后4位不变 | setDemoType() 仅修改主存储的对应位 | **与 COBOL 语义一致**,无需同时清零其他视图 |
| 整区覆写(MOVE 整个 REDEFINES 项) | MOVE 10 TO WRK-DEMO-AREA → 整个8位变为 00000010 | 须同时写入所有视图,或直接操作主存储 | 确认原 COBOL 是"整区覆写"还是"单视图写入"Java 实现须与原程序一致 |
**判定方法**:检查原 COBOL 的 MOVE 目标是整个 REDEFINES 项(如 WRK-DEMO-AREA)还是某个分组项(如 WRK-DEMO-TYPE)。整区覆写→Java 须同时 set 所有视图;单视图写入→Java 仅 set 对应视图。
#### (3) VALUE 子句初始化
COBOL 字段声明时的 VALUE 子句指定初始值。Java 对应方式:
```cobol
03 WRK-R01EOF PIC X(001) VALUE '0'. Java: private String wrkR01Eof = "0";
03 WRK-COMMA-CNT PIC 9(002) COMP. Java: private int wrkCommaCnt; (0)
```
注意:INITIALIZE 后须重新赋值(INITIALIZE 覆盖 VALUE 设定值)。
#### (4) 88 级条件名
COBOL 88 级是条件名(condition name),表示"当宿主字段等于某值时条件为真"。
```cobol
88 WRK-STATUS-ACTIVE VALUE '1'. Java: private boolean isStatusActive() { return "1".equals(wrkCsvStatus); }
88 WRK-STATUS-CANCEL VALUE '9'. Java: private boolean isStatusCancel() { return "9".equals(wrkCsvStatus); }
```
注意:Java 用 `equals()` 比较,不用 `==`String 值比较)。
#### (5) MOVE 定长化语义
COBOL 的 MOVE 是定长传送(自动截断/补空格),Java 需显式定长化:
| COBOL MOVE | Java 实现 | 说明 |
|---|---|---|
| `MOVE "ABC" TO WS-X-10`PIC X(10) | `ConvUtil.padRight("ABC", 10)``"ABC "` | 左对齐,右补空格 |
| `MOVE 123 TO WS-N-5`PIC 9(5) | `ConvUtil.padLeftZero(123, 5)``"00123"` | 左补零 |
| `MOVE WS-X-10 TO W01-REC`(定长记录) | substring 截取 + padRight/padLeftZero | 位置注释对应 05 层定义 |
#### (6) 参考修正(Reference Modification
COBOL 参考修正语法 `M00...(1:1)` 表示取字段第1位开始的1个字符。**COBOL 起始位置为 1**Java substring 起始位置为 0。
```cobol
M00UMKDATS22-03(1:1) Java: substring(0, 1) // 1
```
本项目已用 `padRight("2", 30)` 等价实现(先头1字符上写),无需 substring。但其他程序若使用参考修正,须注意起始位置偏移。
#### (7) UNSTRING TALLYING 语义差异
COBOL 的 UNSTRING TALLYING 统计的是**分隔符个数**Java split(-1) 返回的是**字段个数**
| COBOL | Java | 含义差异 |
|---|---|---|
| `TALLYING IN WRK-COMMA-CNT`8字段需7个分隔符) | `r01Line.split(",", -1).length` = 8 | COBOL: cnt=7Java: length=8 |
| 判定:`IF WRK-COMMA-CNT ≠ 7` | 判定:`fieldCount() ≠ 8` | **等价**cnt+1=length |
注意:若用 split(-1).length 判定,须与 COBOL 的 TALLYING+1 比较,不可直接等同。
#### (8) COMP-3 符号处理
COBOL 的 COMP-3packed decimal)用最后一个 nibble 存储符号(C=正,D=负)。Java 的 long 是二进制补码,无压缩十进制表示。
| 项目 | 处理方式 |
|---|---|
| 正数 | COBOL COMP-3 → Java long:直接转换,无差异 |
| 负数 | 须确认原 COBOL 数据是否含负数;若含负数,须用专用解包方法 |
| 本项目 | 计数器(cunR01Inn 等)均为非负数,无需特殊处理 |
转换时须确认:原 COBOL 的 COMP-3 字段是否有负数可能性。若有,须追加 COMP-3 解包方法到 ConvUtil。
## 四、作业约束
1. 只操作项目根目录(含其子目录)内,不改动系统与本工程以外的任何内容。
2. 源码编码 UTF-8。
3. 不猜不漏:一切业务逻辑不明点记入疑问表,确认后才写码。
4. 编译运行验证以 compile.bat / run.bat 为准,交付前必须通过。
### 语言版本与软件环境(团队共通要求)
| 项目 | 内容 |
|---|---|
| Java 版本 | Java SE 8JDK 1.8)为基准;语法按 Java 8 编写,不使用更高版本特性。Java 11 / 17 语法兼容,可直接编译运行,无需修改源码 |
| 字符编码 | UTF-8 统一(编译 `javac -encoding UTF-8`;运行 `-Dfile.encoding=UTF-8` `chcp 65001` |
| 外部依赖 | 无第三方框架;仅允许 `lib\` 下 JDBC 驱动 jar(当前未配置,DB 程序启用前补充) |
| 构建运行方式 | Windows 批处理直调 `javac` / `java`;无 Maven / Gradle 等构建工具 |
| 本机差异 | JDK 安装路径等本机配置仅存于 `compile.bat``JDK_BIN` 变量 / `JAVA_HOME` 环境变量),不入本文档 |