diff --git a/.vitepress/config.mjs b/.vitepress/config.mjs
index 9338de01..0ec9bdc5 100644
--- a/.vitepress/config.mjs
+++ b/.vitepress/config.mjs
@@ -21,6 +21,10 @@ const links = {
text: "Javaコーディング規約",
link: "/documents/forJava/Javaコーディング規約.html",
},
+ {
+ text: "For Java21",
+ link: "/documents/forJava/Javaコーディング規約_for_21.html",
+ },
{
text: "For Java17",
link: "/documents/forJava/Javaコーディング規約_for_17.html",
diff --git "a/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md" "b/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md"
index ba23122e..a72310b4 100644
--- "a/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md"
+++ "b/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204.md"
@@ -5,7 +5,7 @@ author: Future Enterprise Coding Standards
head:
- - meta
- name: keywords
- content: Javaコーディング規約,Java21,コーディング規約,Java
+ content: Javaコーディング規約,Java25,コーディング規約,Java
---
@@ -193,6 +193,27 @@ head:
}
```
+- 利用しない変数にはアンダースコア `_` を使用する
+ パターンマッチング、ラムダ式の引数、catch句などで、構文上変数は必要だが実際には利用しない場合、意図を明確にするためにアンダースコア `_` (無名変数・無名パターン)を使用することを推奨する。
+
+ 良い例:
+
+ ```java
+ for (String _ : new String[]{"A", "B", "C"}) {
+ // すべての要素もインデックスも無視して”要素の個数分だけ処理を繰り返す”事だけにフォーカスする
+ }
+
+ // anyOpt の内容”の有無”にのみ依存した値を返す
+ anyOpt.map(_ -> "foo").orElseGet(() -> "bar");
+
+ // パターンマッチングの利用しない変数
+ switch (obj) {
+ case String s -> IO.println("String: " + s);
+ case Integer _ -> IO.println("Ignored integer");
+ default -> IO.println("Other type");
+ }
+ ```
+
## 変数全般
- `boolean`変数は`true`/`false` の状態がわかるようにする
@@ -566,6 +587,16 @@ head:
import java.util.*;
```
+- モジュールインポート宣言を利用する
+ `java.util`や`java.io`など、特定のモジュール(例:`java.base`)に属する多数のクラスを利用する場合、個別の`import`文の代わりに`import module java.base;`のようなモジュールインポート宣言の使用を推奨する。
+ ただし、`java.desktop`モジュールをインポートした場合の`List`のように、クラス名が競合する可能性がある場合は、明示的なクラスインポートで解決すること。
+
+ 良い例:
+
+ ```java
+ import module java.base;
+ ```
+
## コンストラクタ
- public 宣言していないクラスには`public`権限のコンストラクタを作らない
@@ -925,6 +956,35 @@ head:
- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない
スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。
+- サブクラスのコンストラクタで`super()`呼び出し前の処理を利用する
+ スーパークラスのコンストラクタに渡す引数の検証や構築が必要な場合、`super()`呼び出しの前にロジックを記述することを推奨する。
+ これにより、従来行われていたprivateコンストラクタへの委譲などの迂回策を避け、より自然なコードを記述が可能。
+ ただし、`super()`呼び出しの前にインスタンスフィールドへアクセスするとコンパイルエラーになる点に注意すること。
+
+ 悪い例:
+
+ ```java
+ class Bar extends Foo {
+ private Bar(List l) {
+ super(l, l);
+ }
+ Bar() {
+ this(List.of("abc", "def"));
+ }
+ }
+ ```
+
+ 良い例:
+
+ ```java
+ class Bar extends Foo {
+ Bar() {
+ var param = List.of("abc", "def"); // super() の前にロジックを記述
+ super(param, param);
+ }
+ }
+ ```
+
## インナークラス
- 原則としてインナークラスは利用しない
@@ -1224,7 +1284,7 @@ head:
for (String s : array) {
builder.append(s);
}
- System.out.println(builder.toString());
+ IO.println(builder.toString());
```
悪い例:
@@ -1234,7 +1294,7 @@ head:
for (String s : array) {
string += s;
}
- System.out.println(string);
+ IO.println(string);
```
@@ -1304,6 +1364,11 @@ head:
.collect(Collectors.joining("\n"));
```
+- 文字列をフォーマットするときは、`formatted()`メソッドの利用を推奨する
+ `String.format`と`String#formatted`で性能・例外はほぼ同等であり、可読性の観点からロケールの指定が不要な多くのケースでメリットを享受できる。
+ ロケールの指定が必要な場合は`String.format`を利用すること。
+ 新規コードでは`formatted()`の利用を基本方針とし、既存コードでの統一はPJで検討すること。
+
## 数値
- 誤差の無い計算をするときは、`BigDecimal` クラスを使う
@@ -1315,7 +1380,7 @@ head:
BigDecimal a = new BigDecimal("1");
BigDecimal b = new BigDecimal("1.0");
if (a.compareTo(b) == 0) {
- System.out.println("一致");
+ IO.println("一致");
}
```
@@ -1326,7 +1391,7 @@ head:
BigDecimal b = new BigDecimal("1.0");
if (a.equals(b)) {
- System.out.println("精度が違うためこの分岐には入らない");
+ IO.println("精度が違うためこの分岐には入らない");
}
```
@@ -1334,17 +1399,118 @@ head:
- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること
`toString()`を利用した場合、指数表記になることがあります。
-## 日付
+## 日付と時刻 (java.timeパッケージ)
-- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う
- 良い例:
+- 日付や時刻の扱いは`java.time`パッケージのAPIを標準とする
+ `java.util.Date`や`java.text.SimpleDateFormat`といった古いAPIは、スレッドセーフではなく、設計上の問題も多いため、**原則として使用を禁止**します。
+
+- 適切な日時クラスを選択する
+
+ | 利用シーン | クラス |
+ | ----------------------------------------------------------------- | ------------------------------------------------------------------------ |
+ | 日付のみ | `LocalDate` |
+ | 時刻のみ | `LocalTime` |
+ | 日付と時刻 | `LocalDateTime` |
+ | タイムゾーンを考慮した日付と時刻 | `ZonedDateTime` |
+ | UTCからのオフセットを考慮した日付と時刻 | `OffsetDateTime` |
+ | 特定の日付や時刻に依存しない期間(時間量)
例: 2時間30分 | `Duration` |
+ | 特定の日付や時刻に依存しない期間(日付ベース)
例: 1年2ヶ月3日 | `Period` |
+ | タイムゾーン | 常に `ZoneId` を使用
`"Asia/Tokyo"`のような地域名で指定することを推奨 |
+
+- 現在の日時を取得する際は、常に`Clock`クラスを依存性注入(DI)して使用することを推奨する
+
+ 良い例:
+
+ ```java
+ // ClockをDIで受け取る
+ public class MyService {
+ private final Clock clock;
+
+ public MyService(Clock clock) {
+ this.clock = clock;
+ }
+
+ public void doSomething() {
+ LocalDateTime now = LocalDateTime.now(clock);
+ // ...
+ }
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ // デフォルトのシステム時刻に依存
+ LocalDateTime now = LocalDateTime.now();
+ ```
+
+- 日時のフォーマットとパースには、スレッドセーフな`DateTimeFormatter`を使用する
+
+ 良い例:
+
+ ```java
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
+ LocalDateTime dateTime = LocalDateTime.parse("2024/10/26 13:45:00", formatter);
+ String formatted = dateTime.format(formatter);
+ ```
+
+- 日時の前後関係を比較する際は、`isAfter()`, `isBefore()`, `isEqual()`メソッドを使用する
+ `<`や`>`などの比較演算子は使用不可
+
+ 良い例:
+
+ ```java
+ if (dateTime1.isAfter(dateTime2)) {
+ // dateTime1がdateTime2より後の場合
+ }
+ ```
+
+- 日時の加算・減算には`plus()`, `minus()`メソッドを使用する
+ エポック秒(ミリ秒)を直接加算・減算するような計算は、うるう年やサマータイムの考慮漏れに繋がるため使用しない
+
+- 期間の計算には`ChronoUnit`や`Duration`/`Period`クラスを使用する
+
+ 良い例:
+
+ ```java
+ // 2週間後を計算
+ LocalDate twoWeeksLater = localDate.plus(2, ChronoUnit.WEEKS);
+ // 90分前を計算
+ LocalDateTime ninetyMinutesAgo = localDateTime.minusMinutes(90);
+ ```
+
+ 悪い例:
+
+ ```java
+ long oneHourInMillis = 60 * 60 * 1000;
+ long nextHour = System.currentTimeMillis() + oneHourInMillis; // タイムゾーンやサマータイムの変更に対応できない
+ ```
+
+- `Duration`と`Period`を使い分ける
+ ナノ秒単位の精度で**時間ベースの期間**(時、分、秒)を扱う場合は`Duration`を使用する。
+ 例:処理時間、タイムアウト設定、有効期限(24時間など)
+
+ **日付ベースの期間**(年、月、日)を扱う場合は`Period`を使用する。
+ 例:契約期間(3ヶ月)、年齢計算
+
+ `Instant`間の差を計算するには`Duration`を使用する。
+ `Duration.between()`または`Instant.until()`を利用する。
+
+ 良い例:
```java
- Date date = new Date();
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
- String s = dateFormat.format(date);
+ Instant start = Instant.now();
+ // ...処理
+ Instant end = Instant.now();
+ Duration duration = Duration.between(start, end);
+ IO.println("処理時間: " + duration.toMillis() + "ミリ秒");
```
+- `ZonedDateTime`と`OffsetDateTime`を使い分ける
+ `ZonedDateTime`: 「東京時間」や「ニューヨーク時間」のように、**特定のタイムゾーンルール(サマータイムを含む)を考慮する必要がある場合**に使用する。ユーザーの地域に合わせた日時を表示する際などに適する。
+
+ `OffsetDateTime`: ログのタイムスタンプやAPI間のデータ交換など、**UTCからの固定オフセット(例: `+09:00`)のみで十分な場合**に使用する。オフセットはサマータイムのルールを保持しないため、将来の日時計算には不向きな場合がある。
+
## 三項演算子
- 入れ子の三項演算子の利用は禁止
@@ -1835,6 +2001,8 @@ head:
- インデントは統合開発環境の提供するフォーマッタに合わせる
- 中間処理の数は 3 つ(3 行)程度までを推奨する
中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。
+- 順序を前提とした中間処理には`gather()`メソッドの利用を検討する
+ 移動平均の計算や、要素を重複させてグルーピングする(スライディングウィンドウ)など、順序や前の要素の状態に依存するステートフルな中間操作を行う場合は、`Gatherers`クラスの利用を検討する。
- コメントは、原則として処理中には記載しない
難解になってしまった場合のみ処理中の記載を認める
@@ -2104,7 +2272,7 @@ head:
```java
static void execute(Object obj) {
if (obj instanceof Point(int x, int y)) {
- System.out.println(x + y);
+ IO.println(x + y);
}
}
```
@@ -2115,7 +2283,7 @@ head:
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
- System.out.println(x+y);
+ IO.println(x+y);
}
```
@@ -2259,7 +2427,7 @@ head:
String message = \"""
テキストブロックです。
\""";
- System.out.println(message);
+ IO.println(message);
""";
```
@@ -2270,14 +2438,14 @@ head:
String message = \"\"\"
テキストブロックです。
\"\"\";
- System.out.println(message);
+ IO.println(message);
""";
String javaCode = """
String message = ""\"
テキストブロックです。
""\";
- System.out.println(message);
+ IO.println(message);
""";
```
@@ -2515,6 +2683,30 @@ Java では 3 種類のコメントが使える。javadoc コメントは`/**`
※ ロジック中に、頻繁に C 風コメントでコメントを書くとまとめてコメントアウトする場合に不便なため、基本的にロジック中では単一行コメントを利用すること。
+## 省略記法
+
+- クラス定義を省略した記法を利用する
+ テストコードや小規模なユーティリティツールなど、本格的なアプリケーション開発以外では、クラス定義を省略したシンプルな記法を利用できる。これにより、`public static void main`といった定型句を省略可能。
+ また、従来の`System.out`に代わり`java.lang.IO`クラスが提供する`println()`メソッドの利用を推奨するが、`println()`の利用自体はPJでのロガー利用方針に準拠する。
+
+ 悪い例:
+
+ ```java
+ public class Hello {
+ public static void main(String[] args) {
+ System.out.println("Hello Java!");
+ }
+ }
+ ```
+
+ 良い例:
+
+ ```java
+ void main() {
+ IO.println("Hello Java!");
+ }
+ ```
+
# パフォーマンス
パフォーマンスを考慮した Java のコーディングについて以下に示す。
diff --git "a/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204_for_21.md" "b/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204_for_21.md"
new file mode 100644
index 00000000..ba23122e
--- /dev/null
+++ "b/documents/forJava/Java\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204_for_21.md"
@@ -0,0 +1,2844 @@
+---
+sidebarDepth: 4
+title: Javaコーディング規約
+author: Future Enterprise Coding Standards
+head:
+ - - meta
+ - name: keywords
+ content: Javaコーディング規約,Java21,コーディング規約,Java
+---
+
+
+
+本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。
+ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。
+また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。
+
+# はじめに
+
+一般に利用・参照されている Java コーディング規約やガイドラインを以下に示す。本規約の作成においても、下記規約類を参照・抜粋している。
+
+| 規約 | 著作者 | URL |
+| ------------------------------------------------------ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
+| Code Conventions for the Java Programming Language | Sun Microsystems | |
+| Writing Robust Java Code | Scott W. Ambler | |
+| オブジェクト倶楽部版 Java コーディング標準 | オブジェクト倶楽部 | |
+| 電通国際情報際サービス版 Java コーディング規約 2004 | 電通国際情報サービス | |
+| JJGuideline (Java - J2EE Conventions and Guidelines) | Stephan.J & JCS Team |
※現在は削除されています |
+| Google Java Style (非公式和訳) | Google | |
+| Acroquest Technology Java コーディング規約 | Acroquest Technology |
※現在は削除されています |
+
+※ Sun Microsystems の規約は Java 草創期から一応の標準という位置づけだったが、オブジェクト指向、及び、その開発環境の普及・発展によって、設計やコーディングにおいて、直接的に有用な知識や豊富な指針を含むような優れた規約や、ツールなどによる機械的な準拠チェックと連携する規約が普及してきている。
+
+# 規約の重要性
+
+標準としての規約を定義し、遵守することの重要性を以下に示す。
+
+- ソフトウェアメンテナンスにおける、可読性・保守性・拡張性の向上
+- 問題を起こしやすい実装を未然に回避することによる、品質・生産性の向上
+- 標準規約を通して得られる一般的な実装知識やノウハウ(=学習効果)
+
+## コーディングの心得
+
+長いプログラムを記述すること(ステップ数)によって生産性が評価されたのは、過去の時代の出来事である。現在は、クラスやメソッドの役割が明確で、ロジックが読みやすく、保守性に優れたプログラムを記述することが評価される。コーディング規約は、コードの書き方に関する一種のパターンと考えることもでき、コードの保守性を向上させる具体的な方法を示している。したがって、規約の一つ一つの意図を理解し、守ることが重要になる。しかし、保守性に優れたコードを作成するためには、コーディング規約を守ることに加えて、良いコードを記述するための基本的な心構えをしっかり心に留めておく必要がある。以下では、その心得について述べる。
+
+【コーディングの心得 5 か条】
+
+1. 見やすさを重視せよ
+2. ネーミングはわかりやすく
+3. サンプルを鵜呑みにしない
+4. 同じコードを二度書かない
+5. 役割は一つに
+
+### 見やすさを重視せよ
+
+「良いコード」の基本は、「他の人が読んでもわかりやすいと感じられるコード」。コードの見やすさは、フォーマットはもちろん、ロジックの簡潔さや API の常識的な使い方などから生まれる。コーディングにあたっては、常に他の人の視点を意識しながら、見やすさに気を配って記述する必要がある。例えば、自分で記述したコードであっても、しばらくたってから読み返してみると理解に時間がかかった経験は誰にもあるはず。「3 日前に書いたコードは他人のコードと同じ」ということもよく言われる。見やすさを重視することは、他の人のためだけでなく自分のためにもなる。コードを読んでもすぐに理解できないような実装は、再考(リファクタリング)の必要がある。
+
+### ネーミングはわかりやすく
+
+コーディングでは、様々な変数やメソッドなどにネーミング(名前付け)する必要がある。ネーミングとは、本来、その対象の本質を表すような名前を考える作業である。大変難易度の高い作業だが、一方で適当に行ってもコードの動作は変わらないため、人によっては手を抜きがちとなる。しかし、ネーミングの良し悪しは、コードの可読性に非常に大きな影響を及ぼす。例えば、「C0001」というクラス名があるとする。これでは、何を表すクラスなのかすぐにはわからないだろう。また、「int p = 5000;」という記述があるとする。プログラマに聞くと、変数名 p は価格(Price)の略だと言うのだが、それならば略さずに、「int price = 5000;」としたほうが分かりやすいはずである。「ネーミングはわかりやすく」の背景には、読んで内容が理解できるという意味で、文章のようなプログラミングを行う、という考え方に基づく。
+
+### サンプルを鵜呑みにしない
+
+サンプルコードを活用すること自体は、著作権等を侵害しなければ問題ない。問題なのは、その内容や背景を理解しないまま、サンプルコードだけを鵜呑みにして、「おまじない」として表面的に適用してしまうことである。コードを「おまじない」ととらえていては、サンプルコードの間違いを気づかないまま適用してしまうこともある。例えば、ストリームのクローズ処理を行っていないサンプルコードであっても、それに気づかずに自分のコードに適用してしまい、後で思わぬ障害を引き起こすという可能性がある。サンプルコードは、そこで説明する内容に絞ったコードが多いため、このような例はよく見られる。また、サンプルコードをそのまま適用した結果、自分が記述すべきコードには必要のないコードが含まれてしまう場合もある。その場合、コードの可読性を下げる原因となる。自分のコードは、自分で深く理解して記述すべきである。
+
+### 同じコードは二度書かない
+
+コードをコピー・ペーストしていませんか?コピー・ペーストしてしまうと、何らかの修正をする際に、全ての個所に同じ修正をする羽目になる。同じコードが現れるようならまとめて一つにし、外に出してコールするような書き方にすべきである。同じコードをまとめる作業は、どちらかといえば、コーディング時よりリファクタリング(ソフトウェアの外部的振る舞いを変更せずに内部構造を改善する作業)で行われることが多い。しかし、コーディング時からできるだけ気をつけておきたいことでもある。
+
+### 役割は一つに
+
+メソッドの役割が明確で、かつ 1 つであれば単体テストが行いやすくなる。つまり、コードの「試験性」が高まる。また、役割が一つであれば、後でコードを変更する際に修正箇所がわかりやすいため、障害修正に要する時間が短くなる。つまり、コードの「保守性」があがることになる。例えば、「チェックをして実行する」機能を実現するために、checkAndDo()メソッドが存在したとする。この場合、このメソッドは check()メソッドと do()メソッドに分割すべきである。なぜなら、checkAndDo()メソッドの check()ロジックに誤りがあった場合、do()メソッドに書かれる内容まで把握する必要が生じるためである。分割してあれば、check()メソッドだけの変更で済む。このことはクラスの設計にもあてはまる。
+
+# ネーミング規約
+
+## 全般
+
+- 大文字・小文字の違いで名前を区別しない。
+
+ 良い例:
+
+ ```java
+ private int carNumber;
+ private int trainNumber;
+ ```
+
+ 悪い例:
+
+ ```java
+ private int num;
+ private int Num;
+ ```
+
+## パッケージ
+
+- パッケージ名はすべて小文字にする
+- パッケージ名は意味のある名前にする
+- サブパッケージ名の重複は可能
+
+## クラス
+
+- クラス名は単語の先頭を大文字にする
+ 良い例:
+
+ ```java
+ public class Entry {
+ ```
+
+ 悪い例:
+
+ ```java
+ public class entry {
+ ```
+
+- インターフェース名、Enum 名、Record 名はクラス名に準ずる
+
+## メソッド
+
+- コンストラクタと同じ名前のメソッドはつくらない
+
+- メソッド名は区切りのみ大文字にする
+ 良い例:
+
+ ```java
+ public String getName() {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public String getname() {
+ //・・・
+ }
+ public String GETNAME() {
+ //・・・
+ }
+ ```
+
+- 変換メソッド名は「"`to`"+オブジェクト名」にする
+ 良い例:
+
+ ```java
+ public String toString() {
+ ```
+
+ 悪い例:
+
+ ```java
+ public String string() {
+ ```
+
+- ゲッターメソッド名は「"`get`"+属性名」にする
+ 型が`boolean`の場合は「"`is`"+属性名」にする
+- セッターメソッド名は「"`set`"+属性名」にする
+
+- `boolean`変数を返すメソッド名は`true`/`false`の状態がわかるようにする
+
+ 良い例:
+
+ ```java
+ public boolean isAsleep() {
+ }
+ public boolean exists() {
+ }
+ public boolean hasExpired() {
+ }
+ ```
+
+## 引数
+
+- メソッドのパラメータ名とインスタンス変数名を一緒にしない
+ ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。
+ アンダースコア `_` をつけての区別は原則禁止とする。
+
+ 良い例:
+
+ ```java
+ public double calc(double rate) {
+ return this.value * rate;
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public double calc(double value) {
+ return this.value * value;
+ }
+
+ public double calc(double _value) {
+ return this.value * _value;
+ }
+ ```
+
+## 変数全般
+
+- `boolean`変数は`true`/`false` の状態がわかるようにする
+
+ 良い例:
+
+ ```java
+ private boolean isOpen;
+ ```
+
+ 悪い例:
+
+ ```java
+ private boolean flag;
+ ```
+
+- 定数は全て`static final`とし、すべて大文字、区切りは"`_`"
+
+ 良い例:
+
+ ```java
+ private static final String SYSTEM_NAME = "販売管理システム";
+ ```
+
+- 変数名は小文字とし、単語の区切りのみ大文字にする
+
+ 良い例:
+
+ ```java
+ private String thisIsString;
+ ```
+
+ 変数名に固有名詞が含まれる場合、先頭をのぞき、単語の区切り以外に大文字を使用してもよい
+
+ 良い例:
+
+ ```java
+ private String thisIsIPAddress;
+ ```
+
+## ローカル変数
+
+- スコープが狭い変数名は省略した名前でもよい
+ 良い例:
+
+ ```java
+ if (・・・) {
+ String s = "・・・・";
+ //変数sを利用した処理 数行
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ String s = "・・・・";
+ if (・・・) {
+ //変数sを利用した処理
+ }
+ ・・・
+ if (・・・) {
+ //変数sを利用した処理
+ }
+ ```
+
+ 変数`s`の利用範囲が広いので役割が明確になる変数名に変更する。
+
+- for 文のループカウンタは、ネストごとに"`i`","`j`","`k`"・・・を使う
+
+## Enum
+
+- Enum 名はクラス名と同じく、単語の先頭を大文字にする
+- 列挙定数は定数と同じく、すべて大文字、区切りは"`_`"
+
+ 良い例:
+
+ ```java
+ enum Season {
+ WINTER,
+ SPRING,
+ SUMMER,
+ FALL
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ enum Season {
+ winter,
+ spring,
+ summer,
+ fall
+ }
+ ```
+
+# コーディング規約
+
+## 全般
+
+- 原則としてオブジェクトの参照にはインターフェースを利用する
+ オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。
+
+ 良い例:
+
+ ```java
+ List list = new ArrayList<>();
+ Map map = new HashMap<>();
+ ```
+
+ 悪い例:
+
+ ```java
+ ArrayList list = new ArrayList<>();
+ HashMap map = new HashMap<>();
+ ```
+
+- 推奨されない API を使用しない
+ アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。
+
+- 使われないコードは書かない
+
+- 宣言は適切な権限で行うこと(`public`, `protected`, `private`)
+
+- `final` を適切に利用する
+ 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。
+
+ 良い例:
+
+ ```java
+ //継承されないクラス
+ public final class CalculateUtils {
+ //・・・
+ }
+
+ //値の変わらない変数(定数)
+ private static final String MESSAGE = "・・・";
+
+ //オーバーライドされないメソッド
+ public final int sum(/*変化させたくない値*/final int... values) {
+ int sumValue = 0;
+ for (/*変化させたくない値*/final int value : values) {
+ sumValue += value;
+ }
+ return sumValue;
+ }
+ ```
+
+## フォーマット
+
+- インデントは空白文字 4 文字分の Tab を使用する
+- 長すぎる行は避ける
+- `{` の後にステートメントを記述しない
+ 良い例:
+
+ ```java
+ if (s == null) {
+ return 0;
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ if (s == null) {return 0;}
+ ```
+
+- 1 行に 2 つ以上のステートメントを記述しない
+ 悪い例:
+
+ ```java
+ } catch (Exception e) {
+ log.error("Error", e);return null;
+ }
+ ```
+
+- カンマの後には空白文字を
+ 良い例:
+
+ ```java
+ process(x, y, z);
+ ```
+
+ 悪い例:
+
+ ```java
+ process(x,y,z);
+ ```
+
+- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する
+ 良い例:
+
+ ```java
+ int a = x;
+ a += 10;
+ ```
+
+ 悪い例:
+
+ ```java
+ int a=x;
+ a+= 10;
+ ```
+
+- for 文内のセミコロンの後には空白文字を挿入する
+ 良い例:
+
+ ```java
+ for (int i = 0; i < array.length; i++) {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ for (int i = 0;i < array.length ;i++) {
+ //・・・
+ }
+ ```
+
+- `++` や `--` とオペランドの間には空白文字を入れない
+ 良い例:
+
+ ```java
+ i++;
+ ```
+
+ 悪い例:
+
+ ```java
+ i ++;
+ ```
+
+- ビット演算子( `|` 、 `&` 、 `^` 、 `<<` 、 `>>` )の前後には空白文字を挿入する
+- 論理演算子( `||` 、`&&`)の前後には空白文字を挿入する
+- 関係演算子( `<` 、 `>` 、 `>=` 、 `<=`、`==`、 `!=` )の前後には空白文字を挿入する
+- 算術演算子( `+` 、 `-` 、 `*` 、 `/` 、 `%` )の前後には空白文字を挿入する
+- return 文ではカッコを使わない
+ 良い例:
+
+ ```java
+ int answer = (a + b + c) * d;
+ return answer;
+ ```
+
+ 悪い例:
+
+ ```java
+ return ((a + b + c) * d);
+ ```
+
+- if などの条件式で boolean の変数を比較しない
+
+ 良い例:
+
+ ```java
+ if (hasStock)
+ ```
+
+ 悪い例:
+
+ ```java
+ if (hasStock == true)
+ ```
+
+- 不等号の向きは左向き( `<` 、 `<=` )にする
+ 良い例:
+
+ ```java
+ if (from <= x && x <= to) {
+ ```
+
+ 悪い例:
+
+ ```java
+ if (x >= from && x <= to) {
+ ```
+
+## コメント
+
+- ファイルの先頭への Copyright の表記について
+ ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。
+ ただし、顧客からの要求があった場合を除く。
+- Javadoc コメントには、少なくとも author と version(クラス)、param と return と exception(メソッド)を記述する
+ - 今後もバージョンアップのリリースが予定されているソースでは、上記に加えて since(バージョン)を記述する
+ - `@Override`のあるメソッドでは、上記に加えて`{@Inherit}`を記述する
+
+- Javadoc クラスヘッダコメントのフォーマットは以下の通り
+
+ 良い例:
+
+ ```java
+ /**
+ * Action(or Bean)クラス メニュー名称
+ *
+ * @author 姓 名
+ * @version バージョン YYYY/MM/DD 説明
+ */
+ ```
+
+- コメントは必要なものだけを簡潔に
+ 悪い例:
+
+ ```java
+ /**
+ * 文字列に変換
+ */
+ @Override
+ public String toString() {
+
+ /**
+ * コピー
+ *
+ * @return コピーしたインスタンス
+ */
+ public Entry copy() {
+ ```
+
+- 不要なコメントは記載しない
+ - コードからすぐわかること・冗長なコメント
+ - 名前の説明
+ コメントではなくわかりやすい名前を付ける。
+ - 別システムで管理している内容
+ ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。
+ - コメントアウトされたコード
+ ソースコード管理システムで管理されている
+- サンプルコードを記載する場合は、`{@snippet}`タグを利用する。
+
+ 外部ファイルから引用する例:
+
+ ```java
+ /**
+ * ユーザー登録処理の例
+ * {@snippet file="UserRegistrationExample.java" region="registration"}
+ */
+ ```
+
+ インラインでサンプルコードを記載する例:
+
+ ```java
+ /**
+ * ユーザー登録処理の例
+ * {@snippet :
+ * User user = new User();
+ * user.setName("田中太郎");
+ * user.setEmail("tanaka@example.com");
+ * userRepository.save(user);
+ * }
+ */
+ ```
+
+## インポート
+
+- `java.lang`パッケージはインポートしない
+
+ 悪い例:
+
+ ```java
+ import java.lang.String;//必要のない記述
+ ```
+
+- 原則として static インポートしない
+ JUnit の作成やフレームワークとして static インポートが推奨されるような場合は利用してもよい
+
+- 原則としてオンデマンドのインポート宣言(type-import-on-demand declaration)(アスタリスク`*`によるインポート) は行わない
+
+ 悪い例:
+
+ ```java
+ import java.util.*;
+ ```
+
+## コンストラクタ
+
+- public 宣言していないクラスには`public`権限のコンストラクタを作らない
+ 良い例:
+
+ ```java
+ class Entry {
+ //・・・
+ Entry(int id) {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ class Entry {
+ //・・・
+ public Entry(int id) {
+ //・・・
+ }
+ ```
+
+- インスタンスメンバを持たない(static メンバのみの)クラスは、`private`権限のコンストラクタを作成する
+
+## メソッド
+
+- オーバーライドさせたくないメソッドは`final`を利用する
+- 戻り値が配列のメソッドで、戻る配列のサイズが 0 の場合、メソッドを使用するクライアントの余計な null チェックのロジックを回避するため、null ではなく長さゼロの配列を戻すようにする。
+ 良い例:
+
+ ```java
+ public String[] toArray(String s) {
+ if (s == null || s.isEmpty()) {
+ return ArrayUtils.EMPTY_STRING_ARRAY;
+ }
+ return new String[] { s };
+ }
+
+ public List toList(String s) {
+ if (s == null || s.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return List.of(s);
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public String[] toArray(String s) {
+ if (s == null || s.isEmpty()) {
+ return null;
+ }
+ return new String[] { s };
+ }
+
+ public List toList(String s) {
+ if (s == null || s.isEmpty()) {
+ return null;
+ }
+ return List.of(s);
+ }
+ ```
+
+- メソッドは 1 つの役割にする
+
+## クラスメソッド
+
+- クラスメソッドを利用するときは、クラス名を使って呼び出す
+ 良い例:
+
+ ```java
+ int comp = Integer.compare(x, y);
+ ```
+
+ 悪い例:
+
+ ```java
+ Integer a = //
+ int comp = a.compare(x, y);
+ ```
+
+## 変数全般
+
+- 1 つのステートメントには 1 つの変数宣言
+ 良い例:
+
+ ```java
+ /** 科目コード */
+ private String code;
+ /** 科目名 */
+ private String name;
+ /** 科目略名 */
+ private String shortName;
+ ```
+
+ 悪い例:
+
+ ```java
+ private String code, name, shortName;
+ ```
+
+- リテラルは使用しない
+ リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。
+ 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合
+
+ 良い例:
+
+ ```java
+ private static final double ONE_MILE_METRE = 1609.344;
+
+ public double mileToMetre(double mi) {
+ return mi * ONE_MILE_METRE;
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public double mileToMetre(double mi) {
+ return mi * 1609.344;
+ }
+ ```
+ - リテラル定数の名前はその値の意味を正しく表現したものにする
+
+ 悪い例:
+
+ ```java
+ private static final int ZERO = 0;
+ ```
+
+- 配列宣言は「`型名[]`」にする
+
+ 良い例:
+
+ ```java
+ private int[] sampleArray = new int[10];
+ ```
+
+ 悪い例:
+
+ ```java
+ private int sampleArray[] = new int[10];
+ ```
+
+- できるだけローカル変数を利用する
+ ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。
+- 定数は`final`で宣言する
+- ローカル変数とインスタンス変数を使いわける
+
+## 定数
+
+- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する
+ `final` ではない `static` な定数は作成しない。
+
+ 良い例:
+
+ ```java
+ public static final String PROTOCOL_HTTP = "http";
+ ```
+
+- 定数( `static` フィールド)に、 `static` ではないメソッドから書き込まない
+
+- 定数は、プリミティブ型もしくは、不変(Immutable)オブジェクトで参照する
+ - 不変`List`の生成には`List.of()`を利用する
+
+ 良い例:
+
+ ```java
+ public static final List VALUES = List.of(1, 2, 3, 4, 5);
+ ```
+
+ 悪い例:
+
+ ```java
+ public static final List VALUES = Arrays.asList(1, 2, 3, 4, 5);
+ ```
+
+ - 不変`Set`の生成には`Set.of()`を利用する
+
+ - 不変`Map`の生成には`Map.of()`を利用する
+
+ 良い例:
+
+ ```java
+ public static final Map VALUES_MAP = Map.of(1, "A", 2, "B", 3, "C");
+ ```
+
+ 悪い例:
+
+ ```java
+ public static final Map VALUES_MAP = new HashMap<>() {
+ {
+ put(1, "A");
+ put(2, "B");
+ put(3, "C");
+ }
+ };
+ ```
+
+ - 不変な配列インスタンスは長さ 0 の配列以外は生成不可能なため、外部から参照される(`public`)定数では利用せず、`List`等への置き換えをすること
+
+ 良い例:
+
+ ```java
+ public static final List VALUES = List.of(1, 2, 3, 4, 5);
+ ```
+
+ 悪い例:
+
+ ```java
+ public static final int[] VALUES = { 1, 2, 3, 4, 5 };
+ ```
+
+## インスタンス変数
+
+- インスタンス変数は`private`にする
+
+ 良い例:
+
+ ```java
+ public class Employee {
+ private long id;
+
+ //・・・
+ //getter/setter
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public class Employee {
+ public long id;
+
+ //・・・
+ //getter/setter
+ }
+ ```
+
+## クラス変数
+
+- `public static final` 宣言した配列を利用しない
+ ※「定数」を参照
+
+- クラス変数にはクラス名を使用してアクセスすること
+
+ 良い例:
+
+ ```java
+ BigDecimal b = BigDecimal.ZERO;
+ ```
+
+ 悪い例:
+
+ ```java
+ BigDecimal a = //
+ BigDecimal b = a.ZERO;
+ ```
+
+
+
+## ローカル変数
+
+- ローカル変数は利用する直前で宣言する
+ 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。
+
+ 良い例:
+
+ ```java
+ for (int i = 0; i < lines.length; i++) {
+ String line = lines[i];
+ //lineの処理
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ String line;
+ for (int i = 0; i < lines.length; i++) {
+ line = lines[i];
+ //lineの処理
+ }
+ ```
+
+- ローカル変数は安易に再利用しない
+ 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。
+
+## 引数
+
+- メソッド引数への代入は行わない
+ 原則として`final`で宣言する。
+
+ 良い例:
+
+ ```java
+ public void add(final int value) {
+ //・・・
+ }
+ ```
+
+## 継承
+
+- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない
+ スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。
+
+ 悪い例:
+
+ ```java
+ public class Abs {
+ protected String name;
+ }
+
+ public class Sub extends Abs {
+ protected String name;//Abs#nameは隠ぺいされる
+ }
+ ```
+
+- スーパークラスのメソッドをオーバーライドするときは@Override アノテーションを指定する。
+
+ 良い例:
+
+ ```java
+ public class Abs {
+ protected void process() {
+
+ }
+ }
+
+ public class Sub extends Abs {
+ @Override
+ protected void process() {
+
+ }
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ public class Abs {
+ protected void process() {
+
+ }
+ }
+
+ public class Sub extends Abs {
+ //@Overrideアノテーションの指定がない
+ protected void process() {
+
+ }
+ }
+ ```
+
+- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない
+ スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。
+
+## インナークラス
+
+- 原則としてインナークラスは利用しない
+ 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。
+ Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。
+
+## メンバー順序
+
+- 以下の順で記述する
+ 1. static フィールド
+ 2. static イニシャライザー
+ 3. static メソッド
+ 4. フィールド
+ 5. イニシャライザー
+ 6. コンストラクター
+ 7. メソッド
+
+- 同一カテゴリー内では以下の可視性の順で記述する
+ 1. public
+ 2. protected
+ 3. パッケージ private
+ 4. private
+
+## インスタンス
+
+- オブジェクト同士は`equals()`メソッドで比較する
+
+ 良い例:
+
+ ```java
+ String s1 = "text";
+ String s2 = "text";
+ if (s1.equals(s2)) {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ String s1 = "text";
+ String s2 = "text";
+ if (s1 == s2) {
+ //・・・
+ }
+ ```
+
+ ただし Enum の場合は`==`演算子を利用して比較する
+
+ `equals()`メソッドで比較する際、左辺のオブジェクトが null にならないように制御すること。
+
+- Class 名を利用した比較をおこなわない
+
+ 良い例:
+
+ ```java
+ if (o instanceof Foo f) {
+ // ...
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ if ("my.Foo".equals(o.getClass().getName())) {
+ Foo f = (Foo)o;
+ // ...
+ }
+ ```
+
+- インスタンスの型キャスト(Class キャスト)が必要な場合はパターンマッチングを使用する
+
+ 良い例:
+
+ ```java
+ if (o instanceof String s) {
+ // ...
+ }
+
+ var str = (o instanceof BigDecimal b) ? b.toPlainString() : String.valueOf(o);
+
+ var empty = o == null ||
+ (o instanceof String s && s.isEmpty()) ||
+ (o instanceof Collection c && c.isEmpty());
+ ```
+
+ 悪い例:
+
+ ```java
+ if (o instanceof String) {
+ String s = (String)o;
+ // ...
+ }
+
+ var str = (o instanceof BigDecimal) ? ((BigDecimal)o).toPlainString() : String.valueOf(o);
+
+ var empty = o == null ||
+ (o instanceof String && ((String)o).isEmpty()) ||
+ (o instanceof Collection && ((Collection)o).isEmpty());
+ ```
+
+- パターンマッチングについては[switch文・式で使用する](#switchでのパターンマッチング)ことも可能。
+
+## 制御構造
+
+- 制御文( `if` , `else` , `while` , `for` , `do while` )の `{ }` は省略しない
+
+ 良い例:
+
+ ```java
+ if (s == null) {
+ return;
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ if (s == null)
+ return;
+ ```
+
+- ステートメントが無い `{}` ブロックを利用しない
+ 悪い例:
+
+ ```java
+ //{}内の記述が無い
+ if (s == null) {
+ }
+ ```
+
+- `if` / `while` の条件式で `=` は利用しない
+ 良い例:
+
+ ```java
+ boolean a =//
+ if (!a) {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ boolean a =//
+ if (a = false) {//コーディングミス
+ //・・・
+ }
+
+
+ boolean a =//
+ boolean b =//
+ if (a = b) {//おそらくコーディングミス
+ //・・・
+ }
+ ```
+
+- `for` と `while` の使い分けを意識する
+- for 文を利用した繰り返し処理中でループ変数の値を変更しない
+ 悪い例:
+
+ ```java
+ String[] array = { /*・・・*/ };
+ for (int i = 0; i < array.length; i++) {
+ //・・・
+ i += 2;//NG
+ }
+
+ for (String s : array) {
+ //・・・
+ s = "string";//NG
+ }
+ ```
+
+- for 文のカウンタは特別な事情がない限り、0 から始める
+- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。
+ 良い例:
+
+ ```java
+ for (int value : array) {
+ //・・・
+ }
+
+ for (String value : list) {
+ //・・・
+ }
+ ```
+
+- 配列をコピーするときは`Arrays.copyOf()`メソッドを利用する
+
+ 良い例:
+
+ ```java
+ int[] newArray = Arrays.copyOf(array, array.length);
+ ```
+
+ 悪い例:
+
+ ```java
+ int[] newArray = new int[array.length];
+ System.arraycopy(array, 0, newArray, 0, array.length);
+ ```
+
+- 繰り返し処理中のオブジェクトの生成は最小限にする
+- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する
+ 良い例:
+
+ ```java
+ CodingKind codingKind = toCodingKind(kind);
+ d = codingKind.encode(s);
+
+ //---
+
+ CodingKind codingKind = toCodingKind(kind);
+ s = codingKind.decode(d);
+ ```
+
+ 悪い例:
+
+ ```java
+ switch (kind) {
+ case 1 ->
+ d = encode1(s);
+ case 2 ->
+ d = encode2(s);
+ }
+
+ //---
+
+ switch (kind) {
+ case 1 ->
+ s = decode1(d);
+ case 2 ->
+ s = decode2(d);
+ }
+ ```
+
+- 繰り返し処理の内部で `try` ブロックを利用しない
+ 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。
+ ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。
+
+ 良い例:
+
+ ```java
+ for (String s : array) {
+ BigDecimal num;
+ try {
+ num = new BigDecimal(s);
+ } catch (NumberFormatException e) {
+ num = BigDecimal.ZERO;
+ }
+ //・・・
+ }
+ ```
+
+## 文字列操作
+
+- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する
+ 良い例:
+
+ ```java
+ String s1 = "text";
+ String s2 = "text";
+ if (s1.equals(s2)) {
+ //・・・
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ String s1 = "text";
+ String s2 = "text";
+ if (s1 == s2) {
+ //・・・
+ }
+ ```
+
+- 文字列リテラルは`new` しない
+ 良い例:
+
+ ```java
+ String s = "";
+ ```
+
+ 悪い例:
+
+ ```java
+ String s = new String();
+ ```
+
+- 更新される文字列には`StringBuilder` クラスを利用する
+ 良い例:
+
+ ```java
+ StringBuilder builder = new StringBuilder();
+ for (String s : array) {
+ builder.append(s);
+ }
+ System.out.println(builder.toString());
+ ```
+
+ 悪い例:
+
+ ```java
+ String string = "";
+ for (String s : array) {
+ string += s;
+ }
+ System.out.println(string);
+ ```
+
+
+ スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する
+
+ [※パフォーマンスについても記載しているので参考にしてください](#文字列連結)
+
+- 1ステートメントのみで行われる文字列の連結には`+`演算子を利用する
+
+ 良い例:
+
+ ```java
+ String s = s1 + s2;
+
+ return s1 + s2 + s3 + s4 + s5;
+ ```
+
+ 悪い例:
+
+ ```java
+ String s = new StringBuilder(s1).append(s2).toString();
+
+ return new StringBuilder(s1).append(s2).append(s3).append(s4).append(s5).toString();
+ ```
+
+- 更新されない文字列には`String` クラスを利用する
+- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する
+ 良い例:
+
+ ```java
+ private static final String PROTOCOL_HTTP = "http";
+
+ if (PROTOCOL_HTTP.equals(url.getProtocol())) {
+
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ private static final String PROTOCOL_HTTP = "http";
+
+ if (url.getProtocol().equals(PROTOCOL_HTTP)) {
+
+ }
+ ```
+
+- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する
+ 良い例:
+
+ ```java
+ int i = 1000;
+ String s = String.valueOf(i);// "1000"
+ s = NumberFormat.getNumberInstance().format(i);// 3桁区切り "1,000"
+
+ boolean b = true;
+ s = String.valueOf(b);// true/false
+ s = BooleanUtils.toStringOnOff(b);// on/off
+ ```
+
+- 文字列の中に、ある文字が含まれているか調べるには、`contains()`メソッドを利用する
+- システム依存記号( `\n` 、 `\r` など)は使用しない。
+ 悪い例:
+
+ ```java
+ String text = Arrays.stream(array)
+ .collect(Collectors.joining("\n"));
+ ```
+
+## 数値
+
+- 誤差の無い計算をするときは、`BigDecimal` クラスを使う
+ 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。
+- 数値の比較は精度に気をつける
+ 良い例:
+
+ ```java
+ BigDecimal a = new BigDecimal("1");
+ BigDecimal b = new BigDecimal("1.0");
+ if (a.compareTo(b) == 0) {
+ System.out.println("一致");
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ BigDecimal a = new BigDecimal("1");
+ BigDecimal b = new BigDecimal("1.0");
+
+ if (a.equals(b)) {
+ System.out.println("精度が違うためこの分岐には入らない");
+ }
+ ```
+
+- 低精度なプリミティブ型にキャストしない
+- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること
+ `toString()`を利用した場合、指数表記になることがあります。
+
+## 日付
+
+- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う
+ 良い例:
+
+ ```java
+ Date date = new Date();
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+ String s = dateFormat.format(date);
+ ```
+
+## 三項演算子
+
+- 入れ子の三項演算子の利用は禁止
+ 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。
+
+## switch 式
+
+- 一つの値を変数に代入するための if-else 文は代わりに switch 式の使用を推奨する
+ switch 式の値を使用することで変数を不変(実質的 final)にでき、代入箇所が分散することによる可読性の低下を防げます。
+
+ 良い例:
+
+ ```java
+ var value = switch (op) {
+ case "add" -> a + b;
+ default -> a - b;
+ };
+ ```
+
+ 悪い例:
+
+ ```java
+ int value;
+ if (op.equals("add")) {
+ value = a + b;
+ } else {
+ value = a - b;
+ }
+ ```
+
+- case 句はなるべく一つの式での記述を推奨する
+ 複雑な式や複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。
+- switch 式は、コーディングミスによるフォールスルーを避けるため、常にアロー構文を使用する
+ からの引用:
+
+ > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。
+ > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。
+
+ 良い例:
+
+ ```java
+ var date = LocalDate.now();
+ var off = switch (date.getDayOfWeek()) {
+ case MONDAY -> {
+ if (myCalendar.isOff(date) || localCalendar.isHoliday(date)) {
+ yield true;
+ }
+ yield localCalendar.isHoliday(date.minusDays(1));
+ }
+ case TUESDAY, WEDNESDAY, THURSDAY, FRIDAY ->
+ myCalendar.isOff(date) || localCalendar.isHoliday(date);
+ case SUNDAY, SATURDAY -> true;
+ };
+ ```
+
+ 悪い例:
+
+ ```java
+ var date = LocalDate.now();
+ var off = switch (date.getDayOfWeek()) {
+ case MONDAY:
+ if (myCalendar.isOff(date) || localCalendar.isHoliday(date)) {
+ yield true;
+ }
+ yield localCalendar.isHoliday(date.minusDays(1));
+ case TUESDAY, WEDNESDAY, THURSDAY, FRIDAY:
+ yield myCalendar.isOff(date) || localCalendar.isHoliday(date);
+ case SUNDAY, SATURDAY:
+ yield true;
+ };
+ ```
+
+- アロー構文の、中カッコ、`yield`を省略できる場合は必ず省略する
+ 良い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ var shortDay = switch (day) {
+ case MONDAY -> "M";
+ case WEDNESDAY -> "W";
+ case FRIDAY -> "F";
+ case TUESDAY, THURSDAY -> "T";
+ case SUNDAY, SATURDAY -> "S";
+ };
+ ```
+
+ 悪い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ var shortDay = switch (day) {
+ case MONDAY -> {
+ yield "M";
+ }
+ case WEDNESDAY -> {
+ yield "W";
+ }
+ case FRIDAY -> {
+ yield "F";
+ }
+ case TUESDAY, THURSDAY -> {
+ yield "T";
+ }
+ case SUNDAY, SATURDAY -> {
+ yield "S";
+ }
+ };
+ ```
+
+- Enum 値の switch 式で case 句が全ての Enum 値をカバーする場合は default 句はデッドコードとなるため記述しない
+ 良い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ var off = switch (day) {
+ case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;
+ case SUNDAY, SATURDAY -> true;
+ };
+
+ var day = DayOfWeek.SUNDAY;
+ var off = switch (day) {
+ case SUNDAY, SATURDAY -> true;
+ default -> false;
+ };
+ ```
+
+ 悪い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ var off = switch (day) {
+ case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;
+ case SUNDAY, SATURDAY -> true;
+ default -> false;
+ };
+ ```
+
+## switch 文
+
+- 代わりに switch 式が使用できる箇所は switch 式を使用する
+ - case 句で`return`を記述する場合は switch 文を使用して良い
+- case 句はなるべく 1 行のステートメントでの記述を推奨する
+ 複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。
+- switch 文は、コーディングミスによるフォールスルーを避けるため、なるべくアロー構文を使用することを推奨する
+ からの引用:
+
+ > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。
+ > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。
+
+ 良い例:
+
+ ```java
+ var date = LocalDate.now();
+ switch (date.getDayOfWeek()) {
+ case MONDAY -> {
+ if (
+ !myCalendar.isOff(date) && !localCalendar.isHoliday(date) &&
+ !localCalendar.isHoliday(date.minusDays(1))
+ ) {
+ work();
+ }
+ }
+ case TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
+ if (!myCalendar.isOff(date) && !localCalendar.isHoliday(date)) {
+ work();
+ }
+ }
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ var date = LocalDate.now();
+ switch (date.getDayOfWeek()) {
+ case MONDAY:
+ if (
+ !myCalendar.isOff(date) && !localCalendar.isHoliday(date) &&
+ !localCalendar.isHoliday(date.minusDays(1))
+ ) {
+ work();
+ }
+ break;
+ case TUESDAY, WEDNESDAY, THURSDAY, FRIDAY:
+ if (!myCalendar.isOff(date) && !localCalendar.isHoliday(date)) {
+ work();
+ }
+ break;
+ }
+ ```
+
+- アロー構文を使用しない(コロンを使用する)場合、複数の値をマッチさせるときの case 句はカンマを使用して列挙する
+ 良い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ boolean off = false;
+ switch (day) {
+ case SUNDAY, SATURDAY:
+ off = true;
+ break;
+ };
+ ```
+
+ 悪い例:
+
+ ```java
+ var day = DayOfWeek.SUNDAY;
+ boolean off = false;
+ switch (day) {
+ case SUNDAY:
+ case SATURDAY:
+ off = true;
+ break;
+ };
+ ```
+
+## switchでのパターンマッチング
+
+- `instanceof`ではなく`switch`文や式に拡張されたパターンマッチングで記載する。
+
+ 良い例:
+
+ ```java
+ static String formatterPatternSwitch(Object obj) {
+ return switch (obj) {
+ case Integer i -> String.format("int %d", i);
+ case Long l -> String.format("long %d", l);
+ case Double d -> String.format("double %f", d);
+ case String s -> String.format("String %s", s);
+ default -> Objects.toString(obj);
+ };
+ }
+ ```
+
+ 悪い例:
+
+ ```java
+ static String formatter(Object obj) {
+ String formatted = "unknown";
+ if (obj instanceof Integer i) {
+ formatted = String.format("int %d", i);
+ } else if (obj instanceof Long l) {
+ formatted = String.format("long %d", l);
+ } else if (obj instanceof Double d) {
+ formatted = String.format("double %f", d);
+ } else if (obj instanceof String s) {
+ formatted = String.format("String %s", s);
+ }
+ return formatted;
+ }
+ ```
+
+## コレクション
+
+- Java2 以降のコレクションクラスを利用する
+ `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。
+- 特定の型のオブジェクトだけを受け入れるコレクションクラスを利用する
+
+ 良い例:
+
+ ```java
+ List