Java基礎:型で金融処理の約束を表す
Javaの文法を暗記するのではなく、MinibankのPayment Serviceを読みながら、型・record・例外・値オブジェクトが金融処理の約束をどう表すかを学びます。
Java / Spring Bootを入口に、金融システムのService・Repository・Transaction設計を読む。
先に学ぶ内容 — Prerequisite: ソフトウェア工学 / 銀行システム学ぶこと — LEARNING GOALS
このページで学ぶこと
- class・record・interfaceの役割
- BigDecimalを使って金額を安全に扱う理由
- コンストラクタ注入と不変なオブジェクトの読み方
体験14 · JAVA BASICS(型で約束を表す)
Javaの型が、金融処理の約束をどう表すか確かめよう
まずは予想をひと言。本文を読んだ後、教材内の参照元で実際のJavaコードを確認します。
- 01まず予想する — PREDICT
まずここだけ:思ったことをひと言書く
Javaで書かれた振込処理のコードは、Mini Bank全体のどの部分を担当していると思いますか?
正解でなくて大丈夫です。「〜だと思う」から始めてみましょう。
ヒント1を見る
画面から入力された金額は、そのままの型でDBまで運ばれると思いますか?
ヒント2を見る
「決まった項目を持つデータ」と「自由に書き換えられるデータ」では、どちらが金融処理に向くでしょうか?
もっと詳しく:この問いで使う専門用語
- recordは、決まった項目を持つ、変更されないデータのまとまりを表すJavaの型です。
- 値オブジェクトは、値と、その値が守る規則を一緒にした型です。
- BigDecimalは、10進数を正確に扱うJavaの数値型です。
- Money(値オブジェクトの一種)は、整数円・正の値・上限という規則を1つの型に閉じ込めます。
日常語で理解する — PLAIN LANGUAGE
まず、ここだけつかむ
Javaは、値の種類と処理の入口・出口を型として明示する言語です。金融処理では、曖昧な値がどこから来てどこへ渡るかを追いやすくなります。
Payment Serviceは外部入力、ユースケース入力、ドメイン値、RPC結果、外部出力を別の型に分けています。似た項目でも責任と信頼範囲が違うためです。
金額にはfloatやdoubleを使わず、BigDecimalとMoneyを使います。整数円・正の値・上限という規則を1つの型へ閉じ込めています。
順番に理解する — DIFFICULT PARTS, STEP BY STEP
難しいポイントを、順番にほどく
専門用語を覚えることより、「なぜ必要か」「このシステムのどこで使うか」を理解することが目標です。
record
決まった項目を持つ、変更されないデータのまとまりです。
層をまたぐ値の契約を短く明確に表せるからです。
CreatePaymentCommandやPendingPaymentがrecordです。
値オブジェクト
値と、その値が守る規則を一緒にした型です。
金額検証を利用箇所ごとに書くと、規則がずれるからです。
Moneyが整数円・正数・上限を守ります。
BigDecimal
10進数を正確に扱うJavaの数値型です。
浮動小数点の丸め誤差を金額へ持ち込まないためです。
HTTPのamountをBigDecimalで受け、Moneyへ変換します。
発展 — ADVANCEDもっと詳しく確認する最初の学習では読まなくても問題ありません。仕組みをもっと深く理解したい場合に開いてください。
Javaコードは、データと振る舞いを型へ閉じ込める
Javaでは、どんな値を受け取り、何を返すかを型として明示します。金融処理では、この明示性がレビューと変更影響の把握に役立ちます。
Payment Serviceでは、HTTP入力、ユースケース入力、ドメイン値、RPC引数、HTTP出力を別々の型にしています。同じように見えるデータでも、信頼できる範囲と責任が異なるためです。
| Javaの要素 | 役割 | Minibankの例 |
|---|---|---|
| class | 状態と処理をまとめる | PaymentController、PaymentApplicationService |
| record | 変更されないデータの組を簡潔に表す | CreatePaymentCommand、PendingPayment |
| enum | 許可された値の集合を表す | ApiErrorCode |
| interfaceとしての境界 | 実装詳細から利用側を分ける考え方 | 現在は具象Gatewayを注入。将来の差し替えではinterface化を検討できる |
recordは、層をまたぐデータの契約
recordは、主に値を運ぶ不変データへ向くJavaの型です。アクセサはamount()のように自動生成されます。
ただしrecordにしただけで入力が安全になるわけではありません。HTTP入力の形式検査、Moneyによる業務上の金額検査、DB関数による残高・KYC検査は別々に必要です。
public record CreatePaymentCommand(
String destinationAccountNumber,
BigDecimal amount,
String requesterName,
String memo
) {}金額にfloatやdoubleを使わない
floatやdoubleは2進浮動小数点であり、10進数を必ずしも正確に表せません。金額の丸め誤差は、台帳や照合の不一致につながります。
MoneyはBigDecimalを受け取り、整数円であること、正の値であること、上限を超えないことを確認してからBigIntegerとして保持します。
- 01HTTPのamountをBigDecimalで受け取る
- 02Money.ofYen()で小数・0以下・上限超過を拒否する
- 03RPCへ渡せるlongへ正確に変換する
- 04表示用にはBigDecimalへ戻す
最初に追うコードの順番
- CreatePaymentRequest:外部から届く値とBean Validation
- CreatePaymentCommand:ControllerからServiceへ渡す値
- Money:金額の不変条件
- PendingPayment:DBが受理した振込依頼
- CreatePaymentResponse:外部へ返す値
体験学習の続き · LEARNING LOOP
ここまで読めましたか?続けて確認してみましょう
型・record・値オブジェクトの考え方を読んだところで、教材内の参照元で実際のJavaコードを確認し、自分の言葉で説明してみます。
- 02仕組みを確かめる — CONCEPT CHECK
画面操作なしで、仕組みを確かめる
この仕組みは、Mini Bankの画面には現れません。次のEvidenceとCode Trail、教材本文だけで理解を進めます。
- 03証拠を確認する — EVIDENCE
何を見たか、1つずつ確かめる
Evidence(判断の根拠となる記録)を確認したらチェックします。各項目の「何を見るか」を手がかりにしてください。
画面を開けない項目は、Source Trail(教材の参照元)と教材の説明で確認できます。失敗を実際に起こす必要はありません。
- 04コードの処理経路を追う — CODE TRAIL
コードを書く必要はありません
ここでは「説明されている仕組みが、実際のMini Bankのどこに実装されているか」を確認します。まずは日本語の役割説明を読み、入力した依頼がどこへ渡るかをつかみましょう。コードの全文を読む必要はありません。
基本の順序は、画面 → API Route(依頼を受ける窓口)→ TransferService(処理をつなぐサービス)→ DB / RPC(記録の保存場所と、その処理の呼び出し)です。まず最初の2つを見て、続くサービスは「もっと詳しく」で確認します。
教材の参照元を確認する — Source Trail ↓整数円・正の値・上限の不変条件を持つ値オブジェクト。BigDecimalからどう検証・変換されるかを探します。
services/payment-service/src/main/java/com/minibank/payment/domain/Money.javaControllerからServiceへ渡す値を表すrecord。外部入力とどう区別されているかを確認します。
services/payment-service/src/main/java/com/minibank/payment/application/CreatePaymentCommand.java - 05自分の言葉で説明する — EXPLAIN
LEVEL 1 — やさしい説明(まずここだけ)
なぜ金額をBigDecimalで受け取った後、そのまま使わずMoney型に変換するのでしょうか? 短い2文を目安に説明してください。
日常語だけで完了できます。専門用語の数や正誤を自動採点するものではありません。
ヒント1を見る
「型」と「検証」という2つの言葉を使って書いてみましょう。
ヒント2を見る
doubleではなくBigDecimalを使う理由を添えてみましょう。
もっと詳しく:LEVEL 2 — 専門用語を使った説明(任意)
record、値オブジェクト、BigDecimalの3つを使って、Payment Serviceが金額をどう安全に扱うか説明してみましょう。
挑戦する場合は、上の説明欄に追記できます。追加しなくても完了できます。
説明の確認ポイント — Checkpoint- 型を分けることで信頼できる範囲を区別できると説明できる
- BigDecimalとMoneyの役割が違うと説明できる
理解を確かめる — CHECK YOUR UNDERSTANDING
3問で理解チェック
答えを頭の中で考えてから、各項目を開いて確認してください。
Q1recordにすれば入力は自動的に安全ですか?
いいえ。recordはデータ構造を表しますが、形式検証や業務規則の検証は別に必要です。
Q2なぜ金額にdoubleを使わないのですか?
10進金額を正確に表せず、丸め誤差が台帳や照合へ影響する可能性があるためです。
Q3Moneyは何を保証しますか?
JPYとして小数がなく、0より大きく、既存システムの上限以内であることを保証します。
完全に暗記する必要はありません。大切な考え方を説明できそうなら押してください。
教材の参照元 — SOURCE TRAIL
根拠と関連教材
CURRENT IMPLEMENTATIONは確認したrepository内の実装です。HISTORICAL IMPLEMENTATIONは導入・修正の履歴で、後続migrationによる再定義があり得ます。RELATED LESSONは教材への案内で、実装の一次Sourceではありません。ASSUMPTIONは仮定、UNKNOWNは未確認を表します。
確認基点: d02eae8914f39cbf06bfe422dc39c71886f82b3e / 2026-09-11。稼働環境への適用確認: UNKNOWN。パス実在の自動検査と、記述した技術的事実の確認は別です。
- 現在の実装 — CURRENT IMPLEMENTATION
services/payment-service/src/main/java/com/minibank/payment/domain/Money.javaMoney整数円の不変条件を持つ値オブジェクト - 現在の実装 — CURRENT IMPLEMENTATION
services/payment-service/src/main/java/com/minibank/payment/application/CreatePaymentCommand.javaCreatePaymentCommandユースケース入力を表すrecord - 現在の実装 — CURRENT IMPLEMENTATION
services/payment-service/src/main/java/com/minibank/payment/domain/PendingPayment.javaPendingPaymentOTP確認待ちの振込依頼