diff --git a/.vscode/settings.json b/.vscode/settings.json index a1d06eed..ec8df704 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,8 @@ { "eslint.validate": ["javascript", "javascriptreact", "vue", "markdown"], "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" + "source.fixAll.eslint": "explicit", + "source.fixAll.markdownlint": "never" }, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, 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..b2822e3a 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" @@ -10,8 +10,8 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに @@ -98,8 +98,8 @@ head: ## クラス -- クラス名は単語の先頭を大文字にする - 良い例: +- クラス名は単語の先頭を大文字にする\ + 良い例: ```java public class Entry { @@ -117,8 +117,8 @@ head: - コンストラクタと同じ名前のメソッドはつくらない -- メソッド名は区切りのみ大文字にする - 良い例: +- メソッド名は区切りのみ大文字にする\ + 良い例: ```java public String getName() { @@ -137,8 +137,8 @@ head: } ``` -- 変換メソッド名は「"`to`"+オブジェクト名」にする - 良い例: +- 変換メソッド名は「"`to`"+オブジェクト名」にする\ + 良い例: ```java public String toString() { @@ -150,8 +150,8 @@ head: public String string() { ``` -- ゲッターメソッド名は「"`get`"+属性名」にする - 型が`boolean`の場合は「"`is`"+属性名」にする +- ゲッターメソッド名は「"`get`"+属性名」にする\ + 型が`boolean`の場合は「"`is`"+属性名」にする - セッターメソッド名は「"`set`"+属性名」にする - `boolean`変数を返すメソッド名は`true`/`false`の状態がわかるようにする @@ -169,9 +169,9 @@ head: ## 引数 -- メソッドのパラメータ名とインスタンス変数名を一緒にしない - ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。 - アンダースコア `_` をつけての区別は原則禁止とする。 +- メソッドのパラメータ名とインスタンス変数名を一緒にしない\ + ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。\ + アンダースコア `_` をつけての区別は原則禁止とする。 良い例: @@ -235,8 +235,8 @@ head: ## ローカル変数 -- スコープが狭い変数名は省略した名前でもよい - 良い例: +- スコープが狭い変数名は省略した名前でもよい\ + 良い例: ```java if (・・・) { @@ -293,8 +293,8 @@ head: ## 全般 -- 原則としてオブジェクトの参照にはインターフェースを利用する - オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 +- 原則としてオブジェクトの参照にはインターフェースを利用する\ + オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 良い例: @@ -310,15 +310,15 @@ head: HashMap map = new HashMap<>(); ``` -- 推奨されない API を使用しない - アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 +- 推奨されない API を使用しない\ + アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 - 使われないコードは書かない - 宣言は適切な権限で行うこと(`public`, `protected`, `private`) -- `final` を適切に利用する - 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 +- `final` を適切に利用する\ + 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 良い例: @@ -345,8 +345,8 @@ head: - インデントは空白文字 4 文字分の Tab を使用する - 長すぎる行は避ける -- `{` の後にステートメントを記述しない - 良い例: +- `{` の後にステートメントを記述しない\ + 良い例: ```java if (s == null) { @@ -360,8 +360,8 @@ head: if (s == null) {return 0;} ``` -- 1 行に 2 つ以上のステートメントを記述しない - 悪い例: +- 1 行に 2 つ以上のステートメントを記述しない\ + 悪い例: ```java } catch (Exception e) { @@ -369,8 +369,8 @@ head: } ``` -- カンマの後には空白文字を - 良い例: +- カンマの後には空白文字を\ + 良い例: ```java process(x, y, z); @@ -382,8 +382,8 @@ head: process(x,y,z); ``` -- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する - 良い例: +- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する\ + 良い例: ```java int a = x; @@ -397,8 +397,8 @@ head: a+= 10; ``` -- for 文内のセミコロンの後には空白文字を挿入する - 良い例: +- for 文内のセミコロンの後には空白文字を挿入する\ + 良い例: ```java for (int i = 0; i < array.length; i++) { @@ -414,8 +414,8 @@ head: } ``` -- `++` や `--` とオペランドの間には空白文字を入れない - 良い例: +- `++` や `--` とオペランドの間には空白文字を入れない\ + 良い例: ```java i++; @@ -431,8 +431,8 @@ head: - 論理演算子( `||` 、`&&`)の前後には空白文字を挿入する - 関係演算子( `<` 、 `>` 、 `>=` 、 `<=`、`==`、 `!=` )の前後には空白文字を挿入する - 算術演算子( `+` 、 `-` 、 `*` 、 `/` 、 `%` )の前後には空白文字を挿入する -- return 文ではカッコを使わない - 良い例: +- return 文ではカッコを使わない\ + 良い例: ```java int answer = (a + b + c) * d; @@ -459,8 +459,8 @@ head: if (hasStock == true) ``` -- 不等号の向きは左向き( `<` 、 `<=` )にする - 良い例: +- 不等号の向きは左向き( `<` 、 `<=` )にする\ + 良い例: ```java if (from <= x && x <= to) { @@ -474,14 +474,14 @@ head: ## コメント -- ファイルの先頭への Copyright の表記について - ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。 +- ファイルの先頭への Copyright の表記について\ + ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。\ ただし、顧客からの要求があった場合を除く。 - Javadoc コメントには、少なくとも author と version(クラス)、param と return と exception(メソッド)を記述する - 今後もバージョンアップのリリースが予定されているソースでは、上記に加えて since(バージョン)を記述する - `@Override`のあるメソッドでは、上記に加えて`{@Inherit}`を記述する -- Javadoc  クラスヘッダコメントのフォーマットは以下の通り +- Javadoc クラスヘッダコメントのフォーマットは以下の通り 良い例: @@ -494,8 +494,8 @@ head: */ ``` -- コメントは必要なものだけを簡潔に - 悪い例: +- コメントは必要なものだけを簡潔に\ + 悪い例: ```java /** @@ -514,12 +514,12 @@ head: - 不要なコメントは記載しない - コードからすぐわかること・冗長なコメント - - 名前の説明 - コメントではなくわかりやすい名前を付ける。 - - 別システムで管理している内容 - ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 - - コメントアウトされたコード - ソースコード管理システムで管理されている + - 名前の説明\ + コメントではなくわかりやすい名前を付ける。 + - 別システムで管理している内容\ + ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 + - コメントアウトされたコード\ + ソースコード管理システムで管理されている - サンプルコードを記載する場合は、`{@snippet}`タグを利用する。 外部ファイルから引用する例: @@ -555,7 +555,7 @@ head: import java.lang.String;//必要のない記述 ``` -- 原則として static インポートしない +- 原則として static インポートしない\ JUnit の作成やフレームワークとして static インポートが推奨されるような場合は利用してもよい - 原則としてオンデマンドのインポート宣言(type-import-on-demand declaration)(アスタリスク`*`によるインポート) は行わない @@ -568,8 +568,8 @@ head: ## コンストラクタ -- public 宣言していないクラスには`public`権限のコンストラクタを作らない - 良い例: +- public 宣言していないクラスには`public`権限のコンストラクタを作らない\ + 良い例: ```java class Entry { @@ -635,8 +635,8 @@ head: ## クラスメソッド -- クラスメソッドを利用するときは、クラス名を使って呼び出す - 良い例: +- クラスメソッドを利用するときは、クラス名を使って呼び出す\ + 良い例: ```java int comp = Integer.compare(x, y); @@ -651,8 +651,8 @@ head: ## 変数全般 -- 1 つのステートメントには 1 つの変数宣言 - 良い例: +- 1 つのステートメントには 1 つの変数宣言\ + 良い例: ```java /** 科目コード */ @@ -669,9 +669,9 @@ head: private String code, name, shortName; ``` -- リテラルは使用しない - リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。 - 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 +- リテラルは使用しない\ + リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。\ + 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 良い例: @@ -690,6 +690,7 @@ head: return mi * 1609.344; } ``` + - リテラル定数の名前はその値の意味を正しく表現したものにする 悪い例: @@ -712,15 +713,15 @@ head: private int sampleArray[] = new int[10]; ``` -- できるだけローカル変数を利用する - ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 +- できるだけローカル変数を利用する\ + ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 - 定数は`final`で宣言する - ローカル変数とインスタンス変数を使いわける ## 定数 -- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する - `final` ではない `static` な定数は作成しない。 +- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する\ + `final` ではない `static` な定数は作成しない。 良い例: @@ -809,8 +810,8 @@ head: ## クラス変数 -- `public static final` 宣言した配列を利用しない - ※「定数」を参照 +- `public static final` 宣言した配列を利用しない\ + ※「定数」を参照 - クラス変数にはクラス名を使用してアクセスすること @@ -827,12 +828,12 @@ head: BigDecimal b = a.ZERO; ``` -
+
## ローカル変数 -- ローカル変数は利用する直前で宣言する - 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 +- ローカル変数は利用する直前で宣言する\ + 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 良い例: @@ -853,13 +854,13 @@ head: } ``` -- ローカル変数は安易に再利用しない - 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 +- ローカル変数は安易に再利用しない\ + 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 ## 引数 -- メソッド引数への代入は行わない - 原則として`final`で宣言する。 +- メソッド引数への代入は行わない\ + 原則として`final`で宣言する。 良い例: @@ -871,8 +872,8 @@ head: ## 継承 -- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない - スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 +- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない\ + スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 悪い例: @@ -922,14 +923,14 @@ head: } ``` -- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない - スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 +- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない\ + スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 ## インナークラス -- 原則としてインナークラスは利用しない - 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。 - Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 +- 原則としてインナークラスは利用しない\ + 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。\ + Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 ## メンバー順序 @@ -1047,8 +1048,8 @@ head: return; ``` -- ステートメントが無い `{}` ブロックを利用しない - 悪い例: +- ステートメントが無い `{}` ブロックを利用しない\ + 悪い例: ```java //{}内の記述が無い @@ -1056,8 +1057,8 @@ head: } ``` -- `if` / `while` の条件式で `=` は利用しない - 良い例: +- `if` / `while` の条件式で `=` は利用しない\ + 良い例: ```java boolean a =// @@ -1083,8 +1084,8 @@ head: ``` - `for` と `while` の使い分けを意識する -- for 文を利用した繰り返し処理中でループ変数の値を変更しない - 悪い例: +- for 文を利用した繰り返し処理中でループ変数の値を変更しない\ + 悪い例: ```java String[] array = { /*・・・*/ }; @@ -1100,8 +1101,8 @@ head: ``` - for 文のカウンタは特別な事情がない限り、0 から始める -- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。 - 良い例: +- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。\ + 良い例: ```java for (int value : array) { @@ -1129,8 +1130,8 @@ head: ``` - 繰り返し処理中のオブジェクトの生成は最小限にする -- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する - 良い例: +- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する\ + 良い例: ```java CodingKind codingKind = toCodingKind(kind); @@ -1162,9 +1163,9 @@ head: } ``` -- 繰り返し処理の内部で `try` ブロックを利用しない - 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。 - ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 +- 繰り返し処理の内部で `try` ブロックを利用しない\ + 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。\ + ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 良い例: @@ -1182,8 +1183,8 @@ head: ## 文字列操作 -- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する - 良い例: +- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する\ + 良い例: ```java String s1 = "text"; @@ -1203,8 +1204,8 @@ head: } ``` -- 文字列リテラルは`new` しない - 良い例: +- 文字列リテラルは`new` しない\ + 良い例: ```java String s = ""; @@ -1216,8 +1217,8 @@ head: String s = new String(); ``` -- 更新される文字列には`StringBuilder` クラスを利用する - 良い例: +- 更新される文字列には`StringBuilder` クラスを利用する\ + 良い例: ```java StringBuilder builder = new StringBuilder(); @@ -1237,7 +1238,7 @@ head: System.out.println(string); ``` -
+
スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する [※パフォーマンスについても記載しているので参考にしてください](#文字列連結) @@ -1261,8 +1262,8 @@ head: ``` - 更新されない文字列には`String` クラスを利用する -- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する - 良い例: +- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する\ + 良い例: ```java private static final String PROTOCOL_HTTP = "http"; @@ -1282,8 +1283,8 @@ head: } ``` -- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する - 良い例: +- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する\ + 良い例: ```java int i = 1000; @@ -1296,8 +1297,8 @@ head: ``` - 文字列の中に、ある文字が含まれているか調べるには、`contains()`メソッドを利用する -- システム依存記号( `\n` 、 `\r` など)は使用しない。 - 悪い例: +- システム依存記号( `\n` 、 `\r` など)は使用しない。\ + 悪い例: ```java String text = Arrays.stream(array) @@ -1306,10 +1307,10 @@ head: ## 数値 -- 誤差の無い計算をするときは、`BigDecimal` クラスを使う - 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 -- 数値の比較は精度に気をつける - 良い例: +- 誤差の無い計算をするときは、`BigDecimal` クラスを使う\ + 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 +- 数値の比較は精度に気をつける\ + 良い例: ```java BigDecimal a = new BigDecimal("1"); @@ -1331,13 +1332,13 @@ head: ``` - 低精度なプリミティブ型にキャストしない -- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること - `toString()`を利用した場合、指数表記になることがあります。 +- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること\ + `toString()`を利用した場合、指数表記になることがあります。 ## 日付 -- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う - 良い例: +- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う\ + 良い例: ```java Date date = new Date(); @@ -1347,13 +1348,13 @@ head: ## 三項演算子 -- 入れ子の三項演算子の利用は禁止 - 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 +- 入れ子の三項演算子の利用は禁止\ + 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 ## switch 式 -- 一つの値を変数に代入するための if-else 文は代わりに switch 式の使用を推奨する - switch 式の値を使用することで変数を不変(実質的 final)にでき、代入箇所が分散することによる可読性の低下を防げます。 +- 一つの値を変数に代入するための if-else 文は代わりに switch 式の使用を推奨する\ + switch 式の値を使用することで変数を不変(実質的 final)にでき、代入箇所が分散することによる可読性の低下を防げます。 良い例: @@ -1375,10 +1376,10 @@ head: } ``` -- case 句はなるべく一つの式での記述を推奨する - 複雑な式や複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 -- switch 式は、コーディングミスによるフォールスルーを避けるため、常にアロー構文を使用する - からの引用: +- case 句はなるべく一つの式での記述を推奨する\ + 複雑な式や複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 +- switch 式は、コーディングミスによるフォールスルーを避けるため、常にアロー構文を使用する\ + からの引用: > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。 > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。 @@ -1417,7 +1418,7 @@ head: }; ``` -- アロー構文の、中カッコ、`yield`を省略できる場合は必ず省略する +- アロー構文の、中カッコ、`yield`を省略できる場合は必ず省略する\ 良い例: ```java @@ -1454,8 +1455,8 @@ head: }; ``` -- Enum 値の switch 式で case 句が全ての Enum 値をカバーする場合は default 句はデッドコードとなるため記述しない - 良い例: +- Enum 値の switch 式で case 句が全ての Enum 値をカバーする場合は default 句はデッドコードとなるため記述しない\ + 良い例: ```java var day = DayOfWeek.SUNDAY; @@ -1486,10 +1487,10 @@ head: - 代わりに switch 式が使用できる箇所は switch 式を使用する - case 句で`return`を記述する場合は switch 文を使用して良い -- case 句はなるべく 1 行のステートメントでの記述を推奨する - 複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 -- switch 文は、コーディングミスによるフォールスルーを避けるため、なるべくアロー構文を使用することを推奨する - からの引用: +- case 句はなるべく 1 行のステートメントでの記述を推奨する\ + 複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 +- switch 文は、コーディングミスによるフォールスルーを避けるため、なるべくアロー構文を使用することを推奨する\ + からの引用: > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。 > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。 @@ -1536,8 +1537,8 @@ head: } ``` -- アロー構文を使用しない(コロンを使用する)場合、複数の値をマッチさせるときの case 句はカンマを使用して列挙する - 良い例: +- アロー構文を使用しない(コロンを使用する)場合、複数の値をマッチさせるときの case 句はカンマを使用して列挙する\ + 良い例: ```java var day = DayOfWeek.SUNDAY; @@ -1600,8 +1601,8 @@ head: ## コレクション -- Java2 以降のコレクションクラスを利用する - `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 +- Java2 以降のコレクションクラスを利用する\ + `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 - 特定の型のオブジェクトだけを受け入れるコレクションクラスを利用する 良い例: @@ -1610,13 +1611,13 @@ head: List> list = new ArrayList<>(); ``` -- `List`のソートは`List.sort()`を利用する - `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。 - Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 -- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する - Java8 で追加されたメソッド。 - 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。 - 具体的には下記のメソッドを利用しないこと。 +- `List`のソートは`List.sort()`を利用する\ + `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。\ + Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 +- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する\ + Java8 で追加されたメソッド。\ + 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。\ + 具体的には下記のメソッドを利用しないこと。 - `Collection#forEach` - `Set#forEach` - `List#forEach` @@ -1639,8 +1640,8 @@ head: }); ``` - ただし、メソッド参照で処理できる場合は`forEach`を利用する。 - (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) + ただし、メソッド参照で処理できる場合は`forEach`を利用する。\ + (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) 良い例: @@ -1656,13 +1657,13 @@ head: } ``` -- `Arrays.asList()`は利用せず、`List.of()`を利用する - Java9 で追加されたメソッド。 - 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 - - `Arrays.asList()`と`List.of()`の違い - `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、 - `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。 - また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 +- `Arrays.asList()`は利用せず、`List.of()`を利用する\ + Java9 で追加されたメソッド。\ + 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 + - `Arrays.asList()`と`List.of()`の違い\ + `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、\ + `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。\ + また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 ## 順序を保持するコレクション @@ -1704,7 +1705,7 @@ head: ## ラムダ式・メソッド参照・コンストラクタ参照 -- ラムダ式が利用できる箇所はラムダ式を利用してよい +- ラムダ式が利用できる箇所はラムダ式を利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#ラムダ式メソッド参照コンストラクタ参照-1) - ただし、メソッド参照・コンストラクタ参照が利用できる場合はメソッド参照・コンストラクタ参照を利用する @@ -1746,7 +1747,7 @@ head: (String s1, String s2) -> s1 + "=" + s2 ``` -- 原則ラムダ式内の行数は 1 行とする +- 原則ラムダ式内の行数は 1 行とする\ 複数行で利用したい場合は、`private`メソッドを作成しメソッド参照を利用する 良い例: @@ -1793,15 +1794,15 @@ head: ## 実質的 final(effectively final) -- 実質的 final を利用する +- 実質的 final を利用する\ 変数宣言に`final`を記載しなくてよい。 ## Stream API -- 利用してよい +- 利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#stream-api-2) -- 並列ストリームは利用しないこと - 悪い例: +- 並列ストリームは利用しないこと\ + 悪い例: ```java Stream s = list.parallelStream(); @@ -1833,10 +1834,10 @@ head: ``` - インデントは統合開発環境の提供するフォーマッタに合わせる -- 中間処理の数は 3 つ(3 行)程度までを推奨する - 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 -- コメントは、原則として処理中には記載しない - 難解になってしまった場合のみ処理中の記載を認める +- 中間処理の数は 3 つ(3 行)程度までを推奨する\ + 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 +- コメントは、原則として処理中には記載しない\ + 難解になってしまった場合のみ処理中の記載を認める 良い例: @@ -1866,9 +1867,9 @@ head: .forEach(this::proc); ``` -- Stream は極力変数代入しないこと - Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。 - 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 +- Stream は極力変数代入しないこと\ + Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。\ + 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 良い例: @@ -1895,8 +1896,8 @@ head: ## Optional -- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと - Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 +- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと\ + Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 良い例: @@ -1912,7 +1913,7 @@ head: Employee employee = employeeOpt.orElseThrow(IllegalArgumentException::new); ``` -
+
直接、値を取り出すことなくOptionalでのみ扱う場合はOptionalを変数代入してもよい。 良い例: @@ -1936,12 +1937,12 @@ head: ## var (Local-Variable Type Inference) -次のリンクも参考にしてください。 +次のリンクも参考にしてください。\ [Style Guidelines for Local Variable Type Inference in Java](https://openjdk.java.net/projects/amber/LVTIstyle.html) -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。 - 各プロジェクトで、例えば以下ののような方針で統一してください。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。\ + 各プロジェクトで、例えば以下ののような方針で統一してください。 1. `var`を利用しない 2. 原則`var`を利用する 3. 右辺で、明確に型がわかる場合は`var`を利用する @@ -2007,8 +2008,8 @@ head: ## レコード -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`record`とクラスと JavaBeans 形式のクラスや Lombok の @Data の使用を混在させるとソースコードの見通しと保守性が悪くなります。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`record`とクラスと JavaBeans 形式のクラスや Lombok の @Data の使用を混在させるとソースコードの見通しと保守性が悪くなります。\ 各プロジェクトで、`record`を利用しないか、`record`の使用しても良い箇所について方針を決めた上で使用するようにしてください。 また、`record`は JavaBeans とは互換性がないため使用している各種ライブラリの対応状況にも注意する必要があります。 @@ -2026,7 +2027,7 @@ head: var uniqueItems = map.values(); ``` -- 次の記述スタイルを標準とする +- 次の記述スタイルを標準とする\ ただし、フォーマッタを導入している場合はフォーマッタに合わせます。 良い例: @@ -2054,14 +2055,14 @@ head: 次にポイントを説明します。 - `{`の後、`}`の前に改行する - - レコードコンポーネント(パラメータ)のカンマの後に改行することを推奨する - レコードコンポーネントが少なく、レコードコンポーネント名からでも意味が理解でき、改行がなくても可読性が低下しない場合は、改行を必要としません。 + - レコードコンポーネント(パラメータ)のカンマの後に改行することを推奨する\ + レコードコンポーネントが少なく、レコードコンポーネント名からでも意味が理解でき、改行がなくても可読性が低下しない場合は、改行を必要としません。\ 改行を推奨する理由は以下です。 - アノテーションを付与したときでも比較的読みやすい(アノテーション引数との混在による可読性の低下の回避) - レコードコンポーネントが多い場合も比較的読みやすい - - レコードコンポーネントが多い場合、レコードコンポーネントへ直接コメントをつけることを検討する - レコードコンポーネントの JavaDoc としては`@param`形式でレコード名の上部に記述しますが、このソースコードをテキストとしてみた場合、レコードコンポーネントの定義と`@param`の説明とで距離が空いてしまう場合があり、型と説明を読むのに時間がかかってしまう可能性があります。 + - レコードコンポーネントが多い場合、レコードコンポーネントへ直接コメントをつけることを検討する\ + レコードコンポーネントの JavaDoc としては`@param`形式でレコード名の上部に記述しますが、このソースコードをテキストとしてみた場合、レコードコンポーネントの定義と`@param`の説明とで距離が空いてしまう場合があり、型と説明を読むのに時間がかかってしまう可能性があります。\ また、使用する IDE によっては、アクセサから宣言へのジャンプを使用すると、レコードコンポーネント(パラメータ)の定義へジャンプするものがあります。レコードコンポーネントにコメントがあればすぐに説明を読むことができますが、JavaDoc しか記述しない場合は、ファイル上部へ移動して対応するレコードコンポーネントの説明を探さなければなりません。 ```java @@ -2096,7 +2097,7 @@ head: ## レコードパターン -- レコードパターンは、データの分解と型チェックを同時に行えるため、冗長なコードの削減、型安全性の向上、IDEによる補完やリファクタリング支援などのメリットがあります。 +- レコードパターンは、データの分解と型チェックを同時に行えるため、冗長なコードの削減、型安全性の向上、IDEによる補完やリファクタリング支援などのメリットがあります。\ これにより、コードの可読性・保守性・安全性が高まるため、レコードを使用する場合はレコードパターンを用いて記述することを推奨します。 良い例: @@ -2121,8 +2122,8 @@ head: ## シールクラス -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`sealed`を利用するとコードの保守性や柔軟性が悪くなります。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`sealed`を利用するとコードの保守性や柔軟性が悪くなります。\ 各プロジェクトで、`sealed`を利用しないか、`sealed`を利用しても良い箇所について方針を決めた上で使用するようにしてください。 方針例: @@ -2132,15 +2133,15 @@ head: - 全体で利用しない など、用途や公開範囲に応じて具体的な方針を決めてください。 - **【補足:シールクラス(sealed classes)とは】** - Javaのsealedクラスは、継承できるサブクラスを明示的に制限する仕組みです。 - これにより、ドメインモデルの制約強化やパターンマッチングの網羅性チェックが可能となり、意図しない拡張や誤用を防ぐことができます。 - 典型的な利用例としては、状態や種類が限定されるドメイン(例:イベント種別、計算式のノード型など)の表現や、パターンマッチング(switch文・式)で全ケースを網羅的に扱いたい場合などが挙げられます。 + **【補足:シールクラス(sealed classes)とは】**\ + Javaのsealedクラスは、継承できるサブクラスを明示的に制限する仕組みです。\ + これにより、ドメインモデルの制約強化やパターンマッチングの網羅性チェックが可能となり、意図しない拡張や誤用を防ぐことができます。\ + 典型的な利用例としては、状態や種類が限定されるドメイン(例:イベント種別、計算式のノード型など)の表現や、パターンマッチング(switch文・式)で全ケースを網羅的に扱いたい場合などが挙げられます。\ メリットは安全性・可読性の向上ですが、柔軟な拡張が難しくなるデメリットもあるため、利用方針を明確に定めてください。 ## テキストブロック -次のリンクも参考にしてください。 +次のリンクも参考にしてください。\ [Programmer's Guide To Text Blocks > Style Guidelines For Text Blocks](https://docs.oracle.com/en/java/javase/17/text-blocks/index.html#style-guidelines-for-text-blocks) - 複数行の文字列を定義する際、文字列連結よりもテキストブロックを使用する @@ -2164,7 +2165,7 @@ head: "より読みやすいソースコードで書くことができます。\n"; ``` -- 単一行の文字列を定義する際、テキストブロックは使用せず文字列リテラルを使用する +- 単一行の文字列を定義する際、テキストブロックは使用せず文字列リテラルを使用する\ ただし、二重引用符(`"`)のエスケープを避ける目的ではテキストブロックを使用しても良い。 良い例: @@ -2320,7 +2321,7 @@ head: 一見すると、読みやすく見えるかもしれませんが、変数名の変更によって簡単に崩れてしまい、修正するために多くの行の変更を強制することになるため、メンテナンス性が低下します。 -- テキストブロックで定義する文字列のインデントは基本的に周辺の Java コードに合わせてインデントする +- テキストブロックで定義する文字列のインデントは基本的に周辺の Java コードに合わせてインデントする\ ただし、横に長い文字列などの可読性向上の目的で左端に揃えるのは良い。 良い例: @@ -2424,8 +2425,8 @@ head: } ``` -- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する - `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 +- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する\ + `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 ## 例外 @@ -2467,19 +2468,19 @@ head: ## よいコメントの鉄則 -- コードを明確化するコメントを書く +- コードを明確化するコメントを書く\ コードにコメントを書く理由は、自分自身、一緒に仕事をしている人、後に関わる開発者にとってコードをより理解しやすいものにするためである。 -- コメント化する価値がないプログラムならば、実行するに値しない +- コメント化する価値がないプログラムならば、実行するに値しない\ 有用な格言。コメントは必須。 -- 過剰な装飾は使わない (例:見出し状のコメント) +- 過剰な装飾は使わない (例:見出し状のコメント)\ 1960 年代から 1970 年代の典型的な COBOL プログラマにはアスタリスク( `*` )でコメントを囲った箱を書く習慣があった。彼らの芸術的な主張を表わしているのかもしれないが、率直に言えばそれは製品に加わるちょっとした価値に比べれば大きな時間の無駄である。かわいいコードではなくきれいなコードを書くはずである。さらに、コードを表示するディスプレイや印刷するプリントに使われるフォントはプロポーショナルだったりそうでなかったりして、箱をきれいに整列させることは難しい。 -- コメントはシンプルに +- コメントはシンプルに\ かつて見たもっとも最良のコメントは、シンプルな要点をまとめた注釈であった。なにも本を書く必要はなく、他の人がコードを理解するに十分な情報を提供するだけでよいのである。 -- コードを書く前に先にコメントを記述する +- コードを書く前に先にコメントを記述する\ コードをコメント化する最良の方法は、コードを書く前にコメントを書くことである。それが、コードを書く前にコードがどのように動作するかについて考えるよい機会となり、コメントの存在を保障することにもつながる。少なくともコードを書いた時にコメントすべきである。コメントによってコードが理解しやすくなることで、コードの開発中にアドバンテージを得ることができる。コードにコメントを書く時間を費やせば、それによって得られるものがある。 -- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない - 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか? - どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 +- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない\ + 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか?\ + どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 ```java if (grandTotal >= 1000.00) { @@ -2491,13 +2492,13 @@ head: - 副作用のある処理の場合は、その内容 (→ メソッドの引数オブジェクトがメソッド内で変更されるケースなど) - 既知のバグ (→ 判明しているが修正しないことにした場合など) - 影響のある事前条件、事後条件 (→ メソッドが正しく動作するための前提について) - - 並行性 (→  マルチスレッドでアクセスされた場合の動作について) + - 並行性 (→ マルチスレッドでアクセスされた場合の動作について) - 該当メソッドの使用例やサンプルコード -- TODO コメント - 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。 - (Eclipse の TODO コメント形式を採用) - 例) +- TODO コメント\ + 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。\ + (Eclipse の TODO コメント形式を採用)\ + 例) ```java //TODO:ワークフローの仕様決定待ち 関連チケット#12345 @@ -2529,7 +2530,7 @@ Java では 3 種類のコメントが使える。javadoc コメントは`/**` Java8 で追加された Stream API での記述は、可読性も高く、簡潔に書けますが、パフォーマンス・性能面で注意が必要な場合があります。 -List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。 +List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。\ 以下に処理例と計測結果を記載します。 - 拡張 for 文 @@ -2564,14 +2565,14 @@ List の処理を行う際、拡張 for 文で処理する場合は Iterator イ | 1 億件 | 949 | 1,026 | | 2 億件 | 1,822 | 2,081 | -小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。 +小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。\ また、Stream API は並列処理(スレッド処理)の機能をサポートしていますので、利用できる場合は並列処理も含めての検証が必要です。 ## ラムダ式・メソッド参照・コンストラクタ参照 -Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。 +Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。\ 積極的な利用を推奨します。 以下に Comparator を生成した場合の計測結果を記載します。 @@ -2639,8 +2640,8 @@ Java8 で追加されたラムダ式・メソッド参照・コンストラク ### 文字列連結(繰り返し) -文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。 -繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。 +文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。\ +繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。\ また、コレクション要素の結合であれば`String#join`が利用できます。 以下に処理例と計測結果を記載します。 @@ -2745,7 +2746,7 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B 20 return ``` -`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。 +`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。\ `StringBuilder`を利用した場合は最適化はされず、記述した通りの処理が行われます。 計測した場合、下記のようになります。 @@ -2761,8 +2762,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B ## List の種類 -`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、 -`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。 +`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、\ +`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。\ `RandomAccess`ではない`List`は、`List#get`などインデックスを利用するような操作のパフォーマンスが低いので注意してください。 以下に処理例と計測結果を記載します。 @@ -2802,13 +2803,13 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B | 100 万件 | 1 | (30 秒以上) | 0(計測不能) | 4 | 0(計測不能) | 4 | | 1,000 万件 | 16 | (30 秒以上) | 8 | 45 | 6 | 44 | -ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、 -ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。 +ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、\ +ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。\ `List#get`での処理をすべて禁止することはできませんが、高いパフォーマンスが求められる場合は`List`の種類にも注目してみてください。 ## BigDecimal の ZERO との比較 -BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。 +BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。\ `compareTo`を利用して`BigDecimal.ZERO`と比較しても同じことができますが、`signum`を利用したほうが効率的です。 以下に処理例と計測結果を記載します。 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_11.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_11.md" index 6f3a14a3..48255556 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_for_11.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_11.md" @@ -10,8 +10,8 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに @@ -98,8 +98,8 @@ head: ## クラス -- クラス名は単語の先頭を大文字にする - 良い例: +- クラス名は単語の先頭を大文字にする\ + 良い例: ```java public class Entry { @@ -117,8 +117,8 @@ head: - コンストラクタと同じ名前のメソッドはつくらない -- メソッド名は区切りのみ大文字にする - 良い例: +- メソッド名は区切りのみ大文字にする\ + 良い例: ```java public String getName() { @@ -137,8 +137,8 @@ head: } ``` -- 変換メソッド名は「"`to`"+オブジェクト名」にする - 良い例: +- 変換メソッド名は「"`to`"+オブジェクト名」にする\ + 良い例: ```java public String toString() { @@ -150,8 +150,8 @@ head: public String string() { ``` -- ゲッターメソッド名は「"`get`"+属性名」にする - 型が`boolean`の場合は「"`is`"+属性名」にする +- ゲッターメソッド名は「"`get`"+属性名」にする\ + 型が`boolean`の場合は「"`is`"+属性名」にする - セッターメソッド名は「"`set`"+属性名」にする - `boolean`変数を返すメソッド名は`true`/`false`の状態がわかるようにする @@ -169,9 +169,9 @@ head: ## 引数 -- メソッドのパラメータ名とインスタンス変数名を一緒にしない - ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。 - アンダースコア `_` をつけての区別は原則禁止とする。 +- メソッドのパラメータ名とインスタンス変数名を一緒にしない\ + ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。\ + アンダースコア `_` をつけての区別は原則禁止とする。 良い例: @@ -235,8 +235,8 @@ head: ## ローカル変数 -- スコープが狭い変数名は省略した名前でもよい - 良い例: +- スコープが狭い変数名は省略した名前でもよい\ + 良い例: ```java if (・・・) { @@ -293,8 +293,8 @@ head: ## 全般 -- 原則としてオブジェクトの参照にはインターフェースを利用する - オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 +- 原則としてオブジェクトの参照にはインターフェースを利用する\ + オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 良い例: @@ -310,15 +310,15 @@ head: HashMap map = new HashMap<>(); ``` -- 推奨されない API を使用しない - アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 +- 推奨されない API を使用しない\ + アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 - 使われないコードは書かない - 宣言は適切な権限で行うこと(`public`, `protected`, `private`) -- `final` を適切に利用する - 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 +- `final` を適切に利用する\ + 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 良い例: @@ -345,8 +345,8 @@ head: - インデントは空白文字 4 文字分の Tab を使用する - 長すぎる行は避ける -- `{` の後にステートメントを記述しない - 良い例: +- `{` の後にステートメントを記述しない\ + 良い例: ```java if (s == null) { @@ -360,8 +360,8 @@ head: if (s == null) {return 0;} ``` -- 1 行に 2 つ以上のステートメントを記述しない - 悪い例: +- 1 行に 2 つ以上のステートメントを記述しない\ + 悪い例: ```java } catch (Exception e) { @@ -369,8 +369,8 @@ head: } ``` -- カンマの後には空白文字を - 良い例: +- カンマの後には空白文字を\ + 良い例: ```java process(x, y, z); @@ -382,8 +382,8 @@ head: process(x,y,z); ``` -- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する - 良い例: +- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する\ + 良い例: ```java int a = x; @@ -397,8 +397,8 @@ head: a+= 10; ``` -- for 文内のセミコロンの後には空白文字を挿入する - 良い例: +- for 文内のセミコロンの後には空白文字を挿入する\ + 良い例: ```java for (int i = 0; i < array.length; i++) { @@ -414,8 +414,8 @@ head: } ``` -- `++` や `--` とオペランドの間には空白文字を入れない - 良い例: +- `++` や `--` とオペランドの間には空白文字を入れない\ + 良い例: ```java i++; @@ -431,8 +431,8 @@ head: - 論理演算子( `||` 、`&&`)の前後には空白文字を挿入する - 関係演算子( `<` 、 `>` 、 `>=` 、 `<=`、`==`、 `!=` )の前後には空白文字を挿入する - 算術演算子( `+` 、 `-` 、 `*` 、 `/` 、 `%` )の前後には空白文字を挿入する -- return 文ではカッコを使わない - 良い例: +- return 文ではカッコを使わない\ + 良い例: ```java int answer = (a + b + c) * d; @@ -459,8 +459,8 @@ head: if (hasStock == true) ``` -- 不等号の向きは左向き( `<` 、 `<=` )にする - 良い例: +- 不等号の向きは左向き( `<` 、 `<=` )にする\ + 良い例: ```java if (from <= x && x <= to) { @@ -474,14 +474,14 @@ head: ## コメント -- ファイルの先頭への Copyright の表記について - ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。 +- ファイルの先頭への Copyright の表記について\ + ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。\ ただし、顧客からの要求があった場合を除く。 - Javadoc コメントには、少なくとも author と version(クラス)、param と return と exception(メソッド)を記述する - 今後もバージョンアップのリリースが予定されているソースでは、上記に加えて since(バージョン)を記述する - `@Override`のあるメソッドでは、上記に加えて`{@Inherit}`を記述する -- Javadoc  クラスヘッダコメントのフォーマットは以下の通り +- Javadoc クラスヘッダコメントのフォーマットは以下の通り 良い例: @@ -494,8 +494,8 @@ head: */ ``` -- コメントは必要なものだけを簡潔に - 悪い例: +- コメントは必要なものだけを簡潔に\ + 悪い例: ```java /** @@ -514,12 +514,12 @@ head: - 不要なコメントは記載しない - コードからすぐわかること・冗長なコメント - - 名前の説明 - コメントではなくわかりやすい名前を付ける。 - - 別システムで管理している内容 - ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 - - コメントアウトされたコード - ソースコード管理システムで管理されている + - 名前の説明\ + コメントではなくわかりやすい名前を付ける。 + - 別システムで管理している内容\ + ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 + - コメントアウトされたコード\ + ソースコード管理システムで管理されている ## インポート @@ -531,7 +531,7 @@ head: import java.lang.String;//必要のない記述 ``` -- 原則として static インポートしない +- 原則として static インポートしない\ JUnit の作成やフレームワークとして static インポートが推奨されるような場合は利用してもよい - 原則としてオンデマンドのインポート宣言(type-import-on-demand declaration)(アスタリスク`*`によるインポート) は行わない @@ -544,8 +544,8 @@ head: ## コンストラクタ -- public 宣言していないクラスには`public`権限のコンストラクタを作らない - 良い例: +- public 宣言していないクラスには`public`権限のコンストラクタを作らない\ + 良い例: ```java class Entry { @@ -611,8 +611,8 @@ head: ## クラスメソッド -- クラスメソッドを利用するときは、クラス名を使って呼び出す - 良い例: +- クラスメソッドを利用するときは、クラス名を使って呼び出す\ + 良い例: ```java int comp = Integer.compare(x, y); @@ -627,8 +627,8 @@ head: ## 変数全般 -- 1 つのステートメントには 1 つの変数宣言 - 良い例: +- 1 つのステートメントには 1 つの変数宣言\ + 良い例: ```java /** 科目コード */ @@ -645,9 +645,9 @@ head: private String code, name, shortName; ``` -- リテラルは使用しない - リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。 - 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 +- リテラルは使用しない\ + リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。\ + 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 良い例: @@ -666,6 +666,7 @@ head: return mi * 1609.344; } ``` + - リテラル定数の名前はその値の意味を正しく表現したものにする 悪い例: @@ -688,15 +689,15 @@ head: private int sampleArray[] = new int[10]; ``` -- できるだけローカル変数を利用する - ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 +- できるだけローカル変数を利用する\ + ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 - 定数は`final`で宣言する - ローカル変数とインスタンス変数を使いわける ## 定数 -- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する - `final` ではない `static` な定数は作成しない。 +- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する\ + `final` ではない `static` な定数は作成しない。 良い例: @@ -785,8 +786,8 @@ head: ## クラス変数 -- `public static final` 宣言した配列を利用しない - ※「定数」を参照 +- `public static final` 宣言した配列を利用しない\ + ※「定数」を参照 - クラス変数にはクラス名を使用してアクセスすること @@ -803,12 +804,12 @@ head: BigDecimal b = a.ZERO; ``` -
+
## ローカル変数 -- ローカル変数は利用する直前で宣言する - 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 +- ローカル変数は利用する直前で宣言する\ + 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 良い例: @@ -829,13 +830,13 @@ head: } ``` -- ローカル変数は安易に再利用しない - 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 +- ローカル変数は安易に再利用しない\ + 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 ## 引数 -- メソッド引数への代入は行わない - 原則として`final`で宣言する。 +- メソッド引数への代入は行わない\ + 原則として`final`で宣言する。 良い例: @@ -847,8 +848,8 @@ head: ## 継承 -- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない - スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 +- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない\ + スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 悪い例: @@ -898,14 +899,14 @@ head: } ``` -- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない - スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 +- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない\ + スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 ## インナークラス -- 原則としてインナークラスは利用しない - 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。 - Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 +- 原則としてインナークラスは利用しない\ + 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。\ + Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 ## メンバー順序 @@ -989,8 +990,8 @@ head: return; ``` -- ステートメントが無い `{}` ブロックを利用しない - 悪い例: +- ステートメントが無い `{}` ブロックを利用しない\ + 悪い例: ```java //{}内の記述が無い @@ -998,8 +999,8 @@ head: } ``` -- `if` / `while` の条件式で `=` は利用しない - 良い例: +- `if` / `while` の条件式で `=` は利用しない\ + 良い例: ```java boolean a =// @@ -1025,8 +1026,8 @@ head: ``` - `for` と `while` の使い分けを意識する -- for 文を利用した繰り返し処理中でループ変数の値を変更しない - 悪い例: +- for 文を利用した繰り返し処理中でループ変数の値を変更しない\ + 悪い例: ```java String[] array = { /*・・・*/ }; @@ -1042,8 +1043,8 @@ head: ``` - for 文のカウンタは特別な事情がない限り、0 から始める -- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。 - 良い例: +- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。\ + 良い例: ```java for (int value : array) { @@ -1071,8 +1072,8 @@ head: ``` - 繰り返し処理中のオブジェクトの生成は最小限にする -- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する - 良い例: +- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する\ + 良い例: ```java CodingKind codingKind = toCodingKind(kind); @@ -1112,9 +1113,9 @@ head: } ``` -- 繰り返し処理の内部で `try` ブロックを利用しない - 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。 - ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 +- 繰り返し処理の内部で `try` ブロックを利用しない\ + 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。\ + ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 良い例: @@ -1132,8 +1133,8 @@ head: ## 文字列操作 -- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する - 良い例: +- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する\ + 良い例: ```java String s1 = "text"; @@ -1153,8 +1154,8 @@ head: } ``` -- 文字列リテラルは`new` しない - 良い例: +- 文字列リテラルは`new` しない\ + 良い例: ```java String s = ""; @@ -1166,8 +1167,8 @@ head: String s = new String(); ``` -- 更新される文字列には`StringBuilder` クラスを利用する - 良い例: +- 更新される文字列には`StringBuilder` クラスを利用する\ + 良い例: ```java StringBuilder builder = new StringBuilder(); @@ -1187,7 +1188,7 @@ head: System.out.println(string); ``` -
+
スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する [※パフォーマンスについても記載しているので参考にしてください](#文字列連結) @@ -1211,8 +1212,8 @@ head: ``` - 更新されない文字列には`String` クラスを利用する -- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する - 良い例: +- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する\ + 良い例: ```java private static final String PROTOCOL_HTTP = "http"; @@ -1232,8 +1233,8 @@ head: } ``` -- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する - 良い例: +- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する\ + 良い例: ```java int i = 1000; @@ -1246,8 +1247,8 @@ head: ``` - 文字列の中に、ある文字が含まれているか調べるには、`contains()`メソッドを利用する -- システム依存記号( `\n` 、 `\r` など)は使用しない。 - 悪い例: +- システム依存記号( `\n` 、 `\r` など)は使用しない。\ + 悪い例: ```java String text = Arrays.stream(array) @@ -1256,10 +1257,10 @@ head: ## 数値 -- 誤差の無い計算をするときは、`BigDecimal` クラスを使う - 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 -- 数値の比較は精度に気をつける - 良い例: +- 誤差の無い計算をするときは、`BigDecimal` クラスを使う\ + 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 +- 数値の比較は精度に気をつける\ + 良い例: ```java BigDecimal a = new BigDecimal("1"); @@ -1281,13 +1282,13 @@ head: ``` - 低精度なプリミティブ型にキャストしない -- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること - `toString()`を利用した場合、指数表記になることがあります。 +- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること\ + `toString()`を利用した場合、指数表記になることがあります。 ## 日付 -- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う - 良い例: +- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う\ + 良い例: ```java Date date = new Date(); @@ -1297,13 +1298,13 @@ head: ## 三項演算子 -- 入れ子の三項演算子の利用は禁止 - 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 +- 入れ子の三項演算子の利用は禁止\ + 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 ## コレクション -- Java2 以降のコレクションクラスを利用する - `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 +- Java2 以降のコレクションクラスを利用する\ + `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 - 特定の型のオブジェクトだけを受け入れるコレクションクラスを利用する 良い例: @@ -1312,13 +1313,13 @@ head: List> list = new ArrayList<>(); ``` -- `List`のソートは`List.sort()`を利用する - `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。 - Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 -- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する - Java8 で追加されたメソッド。 - 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。 - 具体的には下記のメソッドを利用しないこと。 +- `List`のソートは`List.sort()`を利用する\ + `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。\ + Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 +- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する\ + Java8 で追加されたメソッド。\ + 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。\ + 具体的には下記のメソッドを利用しないこと。 - `Collection#forEach` - `Set#forEach` - `List#forEach` @@ -1341,8 +1342,8 @@ head: }); ``` - ただし、メソッド参照で処理できる場合は`forEach`を利用する。 - (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) + ただし、メソッド参照で処理できる場合は`forEach`を利用する。\ + (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) 良い例: @@ -1358,17 +1359,17 @@ head: } ``` -- `Arrays.asList()`は利用せず、`List.of()`を利用する - Java9 で追加されたメソッド。 - 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 - - `Arrays.asList()`と`List.of()`の違い - `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、 - `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。 - また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 +- `Arrays.asList()`は利用せず、`List.of()`を利用する\ + Java9 で追加されたメソッド。\ + 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 + - `Arrays.asList()`と`List.of()`の違い\ + `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、\ + `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。\ + また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 ## ラムダ式・メソッド参照・コンストラクタ参照 -- ラムダ式が利用できる箇所はラムダ式を利用してよい +- ラムダ式が利用できる箇所はラムダ式を利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#ラムダ式メソッド参照コンストラクタ参照-1) - ただし、メソッド参照・コンストラクタ参照が利用できる場合はメソッド参照・コンストラクタ参照を利用する @@ -1410,7 +1411,7 @@ head: (String s1, String s2) -> s1 + "=" + s2 ``` -- 原則ラムダ式内の行数は 1 行とする +- 原則ラムダ式内の行数は 1 行とする\ 複数行で利用したい場合は、`private`メソッドを作成しメソッド参照を利用する 良い例: @@ -1457,15 +1458,15 @@ head: ## 実質的 final(effectively final) -- 実質的 final を利用する +- 実質的 final を利用する\ 変数宣言に`final`を記載しなくてよい。 ## Stream API -- 利用してよい +- 利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#stream-api-2) -- 並列ストリームは利用しないこと - 悪い例: +- 並列ストリームは利用しないこと\ + 悪い例: ```java Stream s = list.parallelStream(); @@ -1497,10 +1498,10 @@ head: ``` - インデントは統合開発環境の提供するフォーマッタに合わせる -- 中間処理の数は 3 つ(3 行)程度までを推奨する - 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 -- コメントは、原則として処理中には記載しない - 難解になってしまった場合のみ処理中の記載を認める +- 中間処理の数は 3 つ(3 行)程度までを推奨する\ + 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 +- コメントは、原則として処理中には記載しない\ + 難解になってしまった場合のみ処理中の記載を認める 良い例: @@ -1530,9 +1531,9 @@ head: .forEach(this::proc); ``` -- Stream は極力変数代入しないこと - Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。 - 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 +- Stream は極力変数代入しないこと\ + Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。\ + 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 良い例: @@ -1559,8 +1560,8 @@ head: ## Optional -- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと - Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 +- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと\ + Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 良い例: @@ -1576,7 +1577,7 @@ head: Employee employee = employeeOpt.orElseThrow(IllegalArgumentException::new); ``` -
+
直接、値を取り出すことなくOptionalでのみ扱う場合はOptionalを変数代入してもよい。 良い例: @@ -1600,12 +1601,12 @@ head: ## var (Local-Variable Type Inference) -次のリンクも参考にしてください。 +次のリンクも参考にしてください。\ [Style Guidelines for Local Variable Type Inference in Java](https://openjdk.java.net/projects/amber/LVTIstyle.html) -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。 - 各プロジェクトで、例えば以下ののような方針で統一してください。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。\ + 各プロジェクトで、例えば以下ののような方針で統一してください。 1. `var`を利用しない 2. 原則`var`を利用する 3. 右辺で、明確に型がわかる場合は`var`を利用する @@ -1695,8 +1696,8 @@ head: } ``` -- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する - `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 +- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する\ + `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 ## 例外 @@ -1738,19 +1739,19 @@ head: ## よいコメントの鉄則 -- コードを明確化するコメントを書く +- コードを明確化するコメントを書く\ コードにコメントを書く理由は、自分自身、一緒に仕事をしている人、後に関わる開発者にとってコードをより理解しやすいものにするためである。 -- コメント化する価値がないプログラムならば、実行するに値しない +- コメント化する価値がないプログラムならば、実行するに値しない\ 有用な格言。コメントは必須。 -- 過剰な装飾は使わない (例:見出し状のコメント) +- 過剰な装飾は使わない (例:見出し状のコメント)\ 1960 年代から 1970 年代の典型的な COBOL プログラマにはアスタリスク( `*` )でコメントを囲った箱を書く習慣があった。彼らの芸術的な主張を表わしているのかもしれないが、率直に言えばそれは製品に加わるちょっとした価値に比べれば大きな時間の無駄である。かわいいコードではなくきれいなコードを書くはずである。さらに、コードを表示するディスプレイや印刷するプリントに使われるフォントはプロポーショナルだったりそうでなかったりして、箱をきれいに整列させることは難しい。 -- コメントはシンプルに +- コメントはシンプルに\ かつて見たもっとも最良のコメントは、シンプルな要点をまとめた注釈であった。なにも本を書く必要はなく、他の人がコードを理解するに十分な情報を提供するだけでよいのである。 -- コードを書く前に先にコメントを記述する +- コードを書く前に先にコメントを記述する\ コードをコメント化する最良の方法は、コードを書く前にコメントを書くことである。それが、コードを書く前にコードがどのように動作するかについて考えるよい機会となり、コメントの存在を保障することにもつながる。少なくともコードを書いた時にコメントすべきである。コメントによってコードが理解しやすくなることで、コードの開発中にアドバンテージを得ることができる。コードにコメントを書く時間を費やせば、それによって得られるものがある。 -- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない - 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか? - どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 +- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない\ + 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか?\ + どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 ```java if (grandTotal >= 1000.00) { @@ -1762,13 +1763,13 @@ head: - 副作用のある処理の場合は、その内容 (→ メソッドの引数オブジェクトがメソッド内で変更されるケースなど) - 既知のバグ (→ 判明しているが修正しないことにした場合など) - 影響のある事前条件、事後条件 (→ メソッドが正しく動作するための前提について) - - 並行性 (→  マルチスレッドでアクセスされた場合の動作について) + - 並行性 (→ マルチスレッドでアクセスされた場合の動作について) - 該当メソッドの使用例やサンプルコード -- TODO コメント - 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。 - (Eclipse の TODO コメント形式を採用) - 例) +- TODO コメント\ + 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。\ + (Eclipse の TODO コメント形式を採用)\ + 例) ```java //TODO:ワークフローの仕様決定待ち 関連チケット#12345 @@ -1800,7 +1801,7 @@ Java では 3 種類のコメントが使える。javadoc コメントは`/**` Java8 で追加された Stream API での記述は、可読性も高く、簡潔に書けますが、パフォーマンス・性能面で注意が必要な場合があります。 -List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。 +List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。\ 以下に処理例と計測結果を記載します。 - 拡張 for 文 @@ -1835,14 +1836,14 @@ List の処理を行う際、拡張 for 文で処理する場合は Iterator イ | 1 億件 | 949 | 1,026 | | 2 億件 | 1,822 | 2,081 | -小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。 +小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。\ また、Stream API は並列処理(スレッド処理)の機能をサポートしていますので、利用できる場合は並列処理も含めての検証が必要です。 ## ラムダ式・メソッド参照・コンストラクタ参照 -Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。 +Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。\ 積極的な利用を推奨します。 以下に Comparator を生成した場合の計測結果を記載します。 @@ -1910,8 +1911,8 @@ Java8 で追加されたラムダ式・メソッド参照・コンストラク ### 文字列連結(繰り返し) -文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。 -繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。 +文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。\ +繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。\ また、コレクション要素の結合であれば`String#join`が利用できます。 以下に処理例と計測結果を記載します。 @@ -2016,7 +2017,7 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B 20 return ``` -`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。 +`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。\ `StringBuilder`を利用した場合は最適化はされず、記述した通りの処理が行われます。 計測した場合、下記のようになります。 @@ -2032,8 +2033,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B ## List の種類 -`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、 -`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。 +`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、\ +`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。\ `RandomAccess`ではない`List`は、`List#get`などインデックスを利用するような操作のパフォーマンスが低いので注意してください。 以下に処理例と計測結果を記載します。 @@ -2073,8 +2074,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B | 100 万件 | 1 | (30 秒以上) | 0(計測不能) | 4 | 0(計測不能) | 4 | | 1,000 万件 | 16 | (30 秒以上) | 8 | 45 | 6 | 44 | -ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、 -ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。 +ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、\ +ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。\ `List#get`での処理をすべて禁止することはできませんが、高いパフォーマンスが求められる場合は`List`の種類にも注目してみてください。 ## String から Integer・Long への変換 @@ -2093,11 +2094,11 @@ String s = "1"; Integer value = new Integer(s); ``` -これらの違いは、 -`new Integer(s)`とした場合、必ず Integer インスタンスが生成されますが、 +これらの違いは、\ +`new Integer(s)`とした場合、必ず Integer インスタンスが生成されますが、\ `Integer.valueOf(s)`とした場合は -128 から 127 の間の数値であればキャッシュから取り出すためインスタンスを生成しません。 -このため、前者の`Integer#valueOf(String)`を利用した記述のほうが効率的です。 +このため、前者の`Integer#valueOf(String)`を利用した記述のほうが効率的です。\ `Long#valueOf(String)`も同様です。 性能差が少ないため、ほとんど問題にはなりませんが、FindBugs 等、静的解析で検出される問題のため、理解が必要です。 @@ -2125,7 +2126,7 @@ String s = "1"; int value = new Integer(s);//生成したIntegerインスタンスをオートボクシングでintにcastしている ``` -「オートボクシング」の説明に記載した通り、性能に差が出るだけでなく、 +「オートボクシング」の説明に記載した通り、性能に差が出るだけでなく、\ 記述から明らかにミスであることが解るため、FindBugs 等、静的解析で検出されるコードです。 `long`への変換の場合は`Long#parseLong(String)`を利用します @@ -2141,7 +2142,7 @@ int value = new Integer(s);//生成したIntegerインスタンスをオート ## BigDecimal の ZERO との比較 -BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。 +BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。\ `compareTo`を利用して`BigDecimal.ZERO`と比較しても同じことができますが、`signum`を利用したほうが効率的です。 以下に処理例と計測結果を記載します。 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_17.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_17.md" index 1e907730..e29350f1 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_for_17.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_17.md" @@ -10,8 +10,8 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに @@ -98,8 +98,8 @@ head: ## クラス -- クラス名は単語の先頭を大文字にする - 良い例: +- クラス名は単語の先頭を大文字にする\ + 良い例: ```java public class Entry { @@ -117,8 +117,8 @@ head: - コンストラクタと同じ名前のメソッドはつくらない -- メソッド名は区切りのみ大文字にする - 良い例: +- メソッド名は区切りのみ大文字にする\ + 良い例: ```java public String getName() { @@ -137,8 +137,8 @@ head: } ``` -- 変換メソッド名は「"`to`"+オブジェクト名」にする - 良い例: +- 変換メソッド名は「"`to`"+オブジェクト名」にする\ + 良い例: ```java public String toString() { @@ -150,8 +150,8 @@ head: public String string() { ``` -- ゲッターメソッド名は「"`get`"+属性名」にする - 型が`boolean`の場合は「"`is`"+属性名」にする +- ゲッターメソッド名は「"`get`"+属性名」にする\ + 型が`boolean`の場合は「"`is`"+属性名」にする - セッターメソッド名は「"`set`"+属性名」にする - `boolean`変数を返すメソッド名は`true`/`false`の状態がわかるようにする @@ -169,9 +169,9 @@ head: ## 引数 -- メソッドのパラメータ名とインスタンス変数名を一緒にしない - ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。 - アンダースコア `_` をつけての区別は原則禁止とする。 +- メソッドのパラメータ名とインスタンス変数名を一緒にしない\ + ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。\ + アンダースコア `_` をつけての区別は原則禁止とする。 良い例: @@ -235,8 +235,8 @@ head: ## ローカル変数 -- スコープが狭い変数名は省略した名前でもよい - 良い例: +- スコープが狭い変数名は省略した名前でもよい\ + 良い例: ```java if (・・・) { @@ -293,8 +293,8 @@ head: ## 全般 -- 原則としてオブジェクトの参照にはインターフェースを利用する - オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 +- 原則としてオブジェクトの参照にはインターフェースを利用する\ + オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 良い例: @@ -310,15 +310,15 @@ head: HashMap map = new HashMap<>(); ``` -- 推奨されない API を使用しない - アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 +- 推奨されない API を使用しない\ + アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 - 使われないコードは書かない - 宣言は適切な権限で行うこと(`public`, `protected`, `private`) -- `final` を適切に利用する - 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 +- `final` を適切に利用する\ + 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 良い例: @@ -345,8 +345,8 @@ head: - インデントは空白文字 4 文字分の Tab を使用する - 長すぎる行は避ける -- `{` の後にステートメントを記述しない - 良い例: +- `{` の後にステートメントを記述しない\ + 良い例: ```java if (s == null) { @@ -360,8 +360,8 @@ head: if (s == null) {return 0;} ``` -- 1 行に 2 つ以上のステートメントを記述しない - 悪い例: +- 1 行に 2 つ以上のステートメントを記述しない\ + 悪い例: ```java } catch (Exception e) { @@ -369,8 +369,8 @@ head: } ``` -- カンマの後には空白文字を - 良い例: +- カンマの後には空白文字を\ + 良い例: ```java process(x, y, z); @@ -382,8 +382,8 @@ head: process(x,y,z); ``` -- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する - 良い例: +- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する\ + 良い例: ```java int a = x; @@ -397,8 +397,8 @@ head: a+= 10; ``` -- for 文内のセミコロンの後には空白文字を挿入する - 良い例: +- for 文内のセミコロンの後には空白文字を挿入する\ + 良い例: ```java for (int i = 0; i < array.length; i++) { @@ -414,8 +414,8 @@ head: } ``` -- `++` や `--` とオペランドの間には空白文字を入れない - 良い例: +- `++` や `--` とオペランドの間には空白文字を入れない\ + 良い例: ```java i++; @@ -431,8 +431,8 @@ head: - 論理演算子( `||` 、`&&`)の前後には空白文字を挿入する - 関係演算子( `<` 、 `>` 、 `>=` 、 `<=`、`==`、 `!=` )の前後には空白文字を挿入する - 算術演算子( `+` 、 `-` 、 `*` 、 `/` 、 `%` )の前後には空白文字を挿入する -- return 文ではカッコを使わない - 良い例: +- return 文ではカッコを使わない\ + 良い例: ```java int answer = (a + b + c) * d; @@ -459,8 +459,8 @@ head: if (hasStock == true) ``` -- 不等号の向きは左向き( `<` 、 `<=` )にする - 良い例: +- 不等号の向きは左向き( `<` 、 `<=` )にする\ + 良い例: ```java if (from <= x && x <= to) { @@ -474,14 +474,14 @@ head: ## コメント -- ファイルの先頭への Copyright の表記について - ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。 +- ファイルの先頭への Copyright の表記について\ + ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。\ ただし、顧客からの要求があった場合を除く。 - Javadoc コメントには、少なくとも author と version(クラス)、param と return と exception(メソッド)を記述する - 今後もバージョンアップのリリースが予定されているソースでは、上記に加えて since(バージョン)を記述する - `@Override`のあるメソッドでは、上記に加えて`{@Inherit}`を記述する -- Javadoc  クラスヘッダコメントのフォーマットは以下の通り +- Javadoc クラスヘッダコメントのフォーマットは以下の通り 良い例: @@ -494,8 +494,8 @@ head: */ ``` -- コメントは必要なものだけを簡潔に - 悪い例: +- コメントは必要なものだけを簡潔に\ + 悪い例: ```java /** @@ -514,12 +514,12 @@ head: - 不要なコメントは記載しない - コードからすぐわかること・冗長なコメント - - 名前の説明 - コメントではなくわかりやすい名前を付ける。 - - 別システムで管理している内容 - ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 - - コメントアウトされたコード - ソースコード管理システムで管理されている + - 名前の説明\ + コメントではなくわかりやすい名前を付ける。 + - 別システムで管理している内容\ + ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 + - コメントアウトされたコード\ + ソースコード管理システムで管理されている ## インポート @@ -531,7 +531,7 @@ head: import java.lang.String;//必要のない記述 ``` -- 原則として static インポートしない +- 原則として static インポートしない\ JUnit の作成やフレームワークとして static インポートが推奨されるような場合は利用してもよい - 原則としてオンデマンドのインポート宣言(type-import-on-demand declaration)(アスタリスク`*`によるインポート) は行わない @@ -544,8 +544,8 @@ head: ## コンストラクタ -- public 宣言していないクラスには`public`権限のコンストラクタを作らない - 良い例: +- public 宣言していないクラスには`public`権限のコンストラクタを作らない\ + 良い例: ```java class Entry { @@ -611,8 +611,8 @@ head: ## クラスメソッド -- クラスメソッドを利用するときは、クラス名を使って呼び出す - 良い例: +- クラスメソッドを利用するときは、クラス名を使って呼び出す\ + 良い例: ```java int comp = Integer.compare(x, y); @@ -627,8 +627,8 @@ head: ## 変数全般 -- 1 つのステートメントには 1 つの変数宣言 - 良い例: +- 1 つのステートメントには 1 つの変数宣言\ + 良い例: ```java /** 科目コード */ @@ -645,9 +645,9 @@ head: private String code, name, shortName; ``` -- リテラルは使用しない - リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。 - 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 +- リテラルは使用しない\ + リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。\ + 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 良い例: @@ -666,6 +666,7 @@ head: return mi * 1609.344; } ``` + - リテラル定数の名前はその値の意味を正しく表現したものにする 悪い例: @@ -688,15 +689,15 @@ head: private int sampleArray[] = new int[10]; ``` -- できるだけローカル変数を利用する - ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 +- できるだけローカル変数を利用する\ + ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 - 定数は`final`で宣言する - ローカル変数とインスタンス変数を使いわける ## 定数 -- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する - `final` ではない `static` な定数は作成しない。 +- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する\ + `final` ではない `static` な定数は作成しない。 良い例: @@ -785,8 +786,8 @@ head: ## クラス変数 -- `public static final` 宣言した配列を利用しない - ※「定数」を参照 +- `public static final` 宣言した配列を利用しない\ + ※「定数」を参照 - クラス変数にはクラス名を使用してアクセスすること @@ -803,12 +804,12 @@ head: BigDecimal b = a.ZERO; ``` -
+
## ローカル変数 -- ローカル変数は利用する直前で宣言する - 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 +- ローカル変数は利用する直前で宣言する\ + 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 良い例: @@ -829,13 +830,13 @@ head: } ``` -- ローカル変数は安易に再利用しない - 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 +- ローカル変数は安易に再利用しない\ + 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 ## 引数 -- メソッド引数への代入は行わない - 原則として`final`で宣言する。 +- メソッド引数への代入は行わない\ + 原則として`final`で宣言する。 良い例: @@ -847,8 +848,8 @@ head: ## 継承 -- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない - スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 +- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない\ + スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 悪い例: @@ -898,14 +899,14 @@ head: } ``` -- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない - スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 +- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない\ + スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 ## インナークラス -- 原則としてインナークラスは利用しない - 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。 - Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 +- 原則としてインナークラスは利用しない\ + 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。\ + Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 ## メンバー順序 @@ -1021,8 +1022,8 @@ head: return; ``` -- ステートメントが無い `{}` ブロックを利用しない - 悪い例: +- ステートメントが無い `{}` ブロックを利用しない\ + 悪い例: ```java //{}内の記述が無い @@ -1030,8 +1031,8 @@ head: } ``` -- `if` / `while` の条件式で `=` は利用しない - 良い例: +- `if` / `while` の条件式で `=` は利用しない\ + 良い例: ```java boolean a =// @@ -1057,8 +1058,8 @@ head: ``` - `for` と `while` の使い分けを意識する -- for 文を利用した繰り返し処理中でループ変数の値を変更しない - 悪い例: +- for 文を利用した繰り返し処理中でループ変数の値を変更しない\ + 悪い例: ```java String[] array = { /*・・・*/ }; @@ -1074,8 +1075,8 @@ head: ``` - for 文のカウンタは特別な事情がない限り、0 から始める -- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。 - 良い例: +- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。\ + 良い例: ```java for (int value : array) { @@ -1103,8 +1104,8 @@ head: ``` - 繰り返し処理中のオブジェクトの生成は最小限にする -- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する - 良い例: +- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する\ + 良い例: ```java CodingKind codingKind = toCodingKind(kind); @@ -1136,9 +1137,9 @@ head: } ``` -- 繰り返し処理の内部で `try` ブロックを利用しない - 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。 - ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 +- 繰り返し処理の内部で `try` ブロックを利用しない\ + 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。\ + ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 良い例: @@ -1156,8 +1157,8 @@ head: ## 文字列操作 -- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する - 良い例: +- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する\ + 良い例: ```java String s1 = "text"; @@ -1177,8 +1178,8 @@ head: } ``` -- 文字列リテラルは`new` しない - 良い例: +- 文字列リテラルは`new` しない\ + 良い例: ```java String s = ""; @@ -1190,8 +1191,8 @@ head: String s = new String(); ``` -- 更新される文字列には`StringBuilder` クラスを利用する - 良い例: +- 更新される文字列には`StringBuilder` クラスを利用する\ + 良い例: ```java StringBuilder builder = new StringBuilder(); @@ -1211,7 +1212,7 @@ head: System.out.println(string); ``` -
+
スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する [※パフォーマンスについても記載しているので参考にしてください](#文字列連結) @@ -1235,8 +1236,8 @@ head: ``` - 更新されない文字列には`String` クラスを利用する -- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する - 良い例: +- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する\ + 良い例: ```java private static final String PROTOCOL_HTTP = "http"; @@ -1256,8 +1257,8 @@ head: } ``` -- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する - 良い例: +- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する\ + 良い例: ```java int i = 1000; @@ -1270,8 +1271,8 @@ head: ``` - 文字列の中に、ある文字が含まれているか調べるには、`contains()`メソッドを利用する -- システム依存記号( `\n` 、 `\r` など)は使用しない。 - 悪い例: +- システム依存記号( `\n` 、 `\r` など)は使用しない。\ + 悪い例: ```java String text = Arrays.stream(array) @@ -1280,10 +1281,10 @@ head: ## 数値 -- 誤差の無い計算をするときは、`BigDecimal` クラスを使う - 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 -- 数値の比較は精度に気をつける - 良い例: +- 誤差の無い計算をするときは、`BigDecimal` クラスを使う\ + 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 +- 数値の比較は精度に気をつける\ + 良い例: ```java BigDecimal a = new BigDecimal("1"); @@ -1305,13 +1306,13 @@ head: ``` - 低精度なプリミティブ型にキャストしない -- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること - `toString()`を利用した場合、指数表記になることがあります。 +- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること\ + `toString()`を利用した場合、指数表記になることがあります。 ## 日付 -- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う - 良い例: +- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う\ + 良い例: ```java Date date = new Date(); @@ -1321,13 +1322,13 @@ head: ## 三項演算子 -- 入れ子の三項演算子の利用は禁止 - 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 +- 入れ子の三項演算子の利用は禁止\ + 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 ## switch 式 -- 一つの値を変数に代入するための if-else 文は代わりに switch 式の使用を推奨する - switch 式の値を使用することで変数を不変(実質的 final)にでき、代入箇所が分散することによる可読性の低下を防げます。 +- 一つの値を変数に代入するための if-else 文は代わりに switch 式の使用を推奨する\ + switch 式の値を使用することで変数を不変(実質的 final)にでき、代入箇所が分散することによる可読性の低下を防げます。 良い例: @@ -1349,10 +1350,10 @@ head: } ``` -- case 句はなるべく一つの式での記述を推奨する - 複雑な式や複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 -- switch 式は、コーディングミスによるフォールスルーを避けるため、常にアロー構文を使用する - からの引用: +- case 句はなるべく一つの式での記述を推奨する\ + 複雑な式や複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 +- switch 式は、コーディングミスによるフォールスルーを避けるため、常にアロー構文を使用する\ + からの引用: > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。 > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。 @@ -1391,7 +1392,7 @@ head: }; ``` -- アロー構文の、中カッコ、`yield`を省略できる場合は必ず省略する +- アロー構文の、中カッコ、`yield`を省略できる場合は必ず省略する\ 良い例: ```java @@ -1428,8 +1429,8 @@ head: }; ``` -- Enum 値の switch 式で case 句が全ての Enum 値をカバーする場合は default 句はデッドコードとなるため記述しない - 良い例: +- Enum 値の switch 式で case 句が全ての Enum 値をカバーする場合は default 句はデッドコードとなるため記述しない\ + 良い例: ```java var day = DayOfWeek.SUNDAY; @@ -1460,10 +1461,10 @@ head: - 代わりに switch 式が使用できる箇所は switch 式を使用する - case 句で`return`を記述する場合は switch 文を使用して良い -- case 句はなるべく 1 行のステートメントでの記述を推奨する - 複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 -- switch 文は、コーディングミスによるフォールスルーを避けるため、なるべくアロー構文を使用することを推奨する - からの引用: +- case 句はなるべく 1 行のステートメントでの記述を推奨する\ + 複雑なステートメントを記述しなければならない場合は、メソッドに分割することを検討してください。 +- switch 文は、コーディングミスによるフォールスルーを避けるため、なるべくアロー構文を使用することを推奨する\ + からの引用: > ノート:`case L ->`ラベルの使用をお薦めします。`case L:`ラベルの使用時は、`break`文または`yield`文の挿入を忘れがちです。これを忘れると、コード内で思いがけないフォール・スルーが発生する場合があります。 > `case L ->`ラベルで、複数の文または式でないコード、あるいは`throw`文を指定するには、それらをブロック内に囲みます。`case`ラベルが生成する値を`yield`文で指定します。 @@ -1510,8 +1511,8 @@ head: } ``` -- アロー構文を使用しない(コロンを使用する)場合、複数の値をマッチさせるときの case 句はカンマを使用して列挙する - 良い例: +- アロー構文を使用しない(コロンを使用する)場合、複数の値をマッチさせるときの case 句はカンマを使用して列挙する\ + 良い例: ```java var day = DayOfWeek.SUNDAY; @@ -1538,8 +1539,8 @@ head: ## コレクション -- Java2 以降のコレクションクラスを利用する - `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 +- Java2 以降のコレクションクラスを利用する\ + `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 - 特定の型のオブジェクトだけを受け入れるコレクションクラスを利用する 良い例: @@ -1548,13 +1549,13 @@ head: List> list = new ArrayList<>(); ``` -- `List`のソートは`List.sort()`を利用する - `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。 - Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 -- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する - Java8 で追加されたメソッド。 - 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。 - 具体的には下記のメソッドを利用しないこと。 +- `List`のソートは`List.sort()`を利用する\ + `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。\ + Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 +- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する\ + Java8 で追加されたメソッド。\ + 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。\ + 具体的には下記のメソッドを利用しないこと。 - `Collection#forEach` - `Set#forEach` - `List#forEach` @@ -1577,8 +1578,8 @@ head: }); ``` - ただし、メソッド参照で処理できる場合は`forEach`を利用する。 - (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) + ただし、メソッド参照で処理できる場合は`forEach`を利用する。\ + (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) 良い例: @@ -1594,17 +1595,17 @@ head: } ``` -- `Arrays.asList()`は利用せず、`List.of()`を利用する - Java9 で追加されたメソッド。 - 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 - - `Arrays.asList()`と`List.of()`の違い - `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、 - `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。 - また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 +- `Arrays.asList()`は利用せず、`List.of()`を利用する\ + Java9 で追加されたメソッド。\ + 配列を`List`に置き換える場合や、単純な固定の`List`を生成する際には`List.of()`を利用する。 + - `Arrays.asList()`と`List.of()`の違い\ + `List.of()`で生成した`List`は、完全に不変(Immutable)な`List`で、\ + `Arrays.asList()`で生成した`List`は、サイズのみ不変で、`set`等による値の操作が可能な`List`です。\ + また、`set`を行った場合、`Arrays.asList()`に与えられた配列インスタンスにも影響します。 ## ラムダ式・メソッド参照・コンストラクタ参照 -- ラムダ式が利用できる箇所はラムダ式を利用してよい +- ラムダ式が利用できる箇所はラムダ式を利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#ラムダ式メソッド参照コンストラクタ参照-1) - ただし、メソッド参照・コンストラクタ参照が利用できる場合はメソッド参照・コンストラクタ参照を利用する @@ -1646,7 +1647,7 @@ head: (String s1, String s2) -> s1 + "=" + s2 ``` -- 原則ラムダ式内の行数は 1 行とする +- 原則ラムダ式内の行数は 1 行とする\ 複数行で利用したい場合は、`private`メソッドを作成しメソッド参照を利用する 良い例: @@ -1693,15 +1694,15 @@ head: ## 実質的 final(effectively final) -- 実質的 final を利用する +- 実質的 final を利用する\ 変数宣言に`final`を記載しなくてよい。 ## Stream API -- 利用してよい +- 利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#stream-api-2) -- 並列ストリームは利用しないこと - 悪い例: +- 並列ストリームは利用しないこと\ + 悪い例: ```java Stream s = list.parallelStream(); @@ -1733,10 +1734,10 @@ head: ``` - インデントは統合開発環境の提供するフォーマッタに合わせる -- 中間処理の数は 3 つ(3 行)程度までを推奨する - 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 -- コメントは、原則として処理中には記載しない - 難解になってしまった場合のみ処理中の記載を認める +- 中間処理の数は 3 つ(3 行)程度までを推奨する\ + 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 +- コメントは、原則として処理中には記載しない\ + 難解になってしまった場合のみ処理中の記載を認める 良い例: @@ -1766,9 +1767,9 @@ head: .forEach(this::proc); ``` -- Stream は極力変数代入しないこと - Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。 - 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 +- Stream は極力変数代入しないこと\ + Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。\ + 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 良い例: @@ -1795,8 +1796,8 @@ head: ## Optional -- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと - Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 +- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと\ + Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 良い例: @@ -1812,7 +1813,7 @@ head: Employee employee = employeeOpt.orElseThrow(IllegalArgumentException::new); ``` -
+
直接、値を取り出すことなくOptionalでのみ扱う場合はOptionalを変数代入してもよい。 良い例: @@ -1836,12 +1837,12 @@ head: ## var (Local-Variable Type Inference) -次のリンクも参考にしてください。 +次のリンクも参考にしてください。\ [Style Guidelines for Local Variable Type Inference in Java](https://openjdk.java.net/projects/amber/LVTIstyle.html) -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。 - 各プロジェクトで、例えば以下ののような方針で統一してください。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`var`を混在させるとソースコードの見通しと保守性が悪くなります。\ + 各プロジェクトで、例えば以下ののような方針で統一してください。 1. `var`を利用しない 2. 原則`var`を利用する 3. 右辺で、明確に型がわかる場合は`var`を利用する @@ -1907,8 +1908,8 @@ head: ## レコード -- 明確な方針で、利用する・利用しないを統一すること - 方針無く、`record`とクラスと JavaBeans 形式のクラスや Lombok の @Data の使用を混在させるとソースコードの見通しと保守性が悪くなります。 +- 明確な方針で、利用する・利用しないを統一すること\ + 方針無く、`record`とクラスと JavaBeans 形式のクラスや Lombok の @Data の使用を混在させるとソースコードの見通しと保守性が悪くなります。\ 各プロジェクトで、`record`を利用しないか、`record`の使用しても良い箇所について方針を決めた上で使用するようにしてください。 また、`record`は JavaBeans とは互換性がないため使用している各種ライブラリの対応状況にも注意する必要があります。 @@ -1926,7 +1927,7 @@ head: var uniqueItems = map.values(); ``` -- 次の記述スタイルを標準とする +- 次の記述スタイルを標準とする\ ただし、フォーマッタを導入している場合はフォーマッタに合わせます。 良い例: @@ -1954,14 +1955,14 @@ head: 次にポイントを説明します。 - `{`の後、`}`の前に改行する - - レコードコンポーネント(パラメータ)のカンマの後に改行することを推奨する - レコードコンポーネントが少なく、レコードコンポーネント名からでも意味が理解でき、改行がなくても可読性が低下しない場合は、改行を必要としません。 + - レコードコンポーネント(パラメータ)のカンマの後に改行することを推奨する\ + レコードコンポーネントが少なく、レコードコンポーネント名からでも意味が理解でき、改行がなくても可読性が低下しない場合は、改行を必要としません。\ 改行を推奨する理由は以下です。 - アノテーションを付与したときでも比較的読みやすい(アノテーション引数との混在による可読性の低下の回避) - レコードコンポーネントが多い場合も比較的読みやすい - - レコードコンポーネントが多い場合、レコードコンポーネントへ直接コメントをつけることを検討する - レコードコンポーネントの JavaDoc としては`@param`形式でレコード名の上部に記述しますが、このソースコードをテキストとしてみた場合、レコードコンポーネントの定義と`@param`の説明とで距離が空いてしまう場合があり、型と説明を読むのに時間がかかってしまう可能性があります。 + - レコードコンポーネントが多い場合、レコードコンポーネントへ直接コメントをつけることを検討する\ + レコードコンポーネントの JavaDoc としては`@param`形式でレコード名の上部に記述しますが、このソースコードをテキストとしてみた場合、レコードコンポーネントの定義と`@param`の説明とで距離が空いてしまう場合があり、型と説明を読むのに時間がかかってしまう可能性があります。\ また、使用する IDE によっては、アクセサから宣言へのジャンプを使用すると、レコードコンポーネント(パラメータ)の定義へジャンプするものがあります。レコードコンポーネントにコメントがあればすぐに説明を読むことができますが、JavaDoc しか記述しない場合は、ファイル上部へ移動して対応するレコードコンポーネントの説明を探さなければなりません。 ```java @@ -1996,7 +1997,7 @@ head: ## テキストブロック -次のリンクも参考にしてください。 +次のリンクも参考にしてください。\ [Programmer's Guide To Text Blocks > Style Guidelines For Text Blocks](https://docs.oracle.com/en/java/javase/17/text-blocks/index.html#style-guidelines-for-text-blocks) - 複数行の文字列を定義する際、文字列連結よりもテキストブロックを使用する @@ -2020,7 +2021,7 @@ head: "より読みやすいソースコードで書くことができます。\n"; ``` -- 単一行の文字列を定義する際、テキストブロックは使用せず文字列リテラルを使用する +- 単一行の文字列を定義する際、テキストブロックは使用せず文字列リテラルを使用する\ ただし、二重引用符(`"`)のエスケープを避ける目的ではテキストブロックを使用しても良い。 良い例: @@ -2176,7 +2177,7 @@ head: 一見すると、読みやすく見えるかもしれませんが、変数名の変更によって簡単に崩れてしまい、修正するために多くの行の変更を強制することになるため、メンテナンス性が低下します。 -- テキストブロックで定義する文字列のインデントは基本的に周辺の Java コードに合わせてインデントする +- テキストブロックで定義する文字列のインデントは基本的に周辺の Java コードに合わせてインデントする\ ただし、横に長い文字列などの可読性向上の目的で左端に揃えるのは良い。 良い例: @@ -2280,8 +2281,8 @@ head: } ``` -- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する - `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 +- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する\ + `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 ## 例外 @@ -2323,19 +2324,19 @@ head: ## よいコメントの鉄則 -- コードを明確化するコメントを書く +- コードを明確化するコメントを書く\ コードにコメントを書く理由は、自分自身、一緒に仕事をしている人、後に関わる開発者にとってコードをより理解しやすいものにするためである。 -- コメント化する価値がないプログラムならば、実行するに値しない +- コメント化する価値がないプログラムならば、実行するに値しない\ 有用な格言。コメントは必須。 -- 過剰な装飾は使わない (例:見出し状のコメント) +- 過剰な装飾は使わない (例:見出し状のコメント)\ 1960 年代から 1970 年代の典型的な COBOL プログラマにはアスタリスク( `*` )でコメントを囲った箱を書く習慣があった。彼らの芸術的な主張を表わしているのかもしれないが、率直に言えばそれは製品に加わるちょっとした価値に比べれば大きな時間の無駄である。かわいいコードではなくきれいなコードを書くはずである。さらに、コードを表示するディスプレイや印刷するプリントに使われるフォントはプロポーショナルだったりそうでなかったりして、箱をきれいに整列させることは難しい。 -- コメントはシンプルに +- コメントはシンプルに\ かつて見たもっとも最良のコメントは、シンプルな要点をまとめた注釈であった。なにも本を書く必要はなく、他の人がコードを理解するに十分な情報を提供するだけでよいのである。 -- コードを書く前に先にコメントを記述する +- コードを書く前に先にコメントを記述する\ コードをコメント化する最良の方法は、コードを書く前にコメントを書くことである。それが、コードを書く前にコードがどのように動作するかについて考えるよい機会となり、コメントの存在を保障することにもつながる。少なくともコードを書いた時にコメントすべきである。コメントによってコードが理解しやすくなることで、コードの開発中にアドバンテージを得ることができる。コードにコメントを書く時間を費やせば、それによって得られるものがある。 -- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない - 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか? - どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 +- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない\ + 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか?\ + どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 ```java if (grandTotal >= 1000.00) { @@ -2347,13 +2348,13 @@ head: - 副作用のある処理の場合は、その内容 (→ メソッドの引数オブジェクトがメソッド内で変更されるケースなど) - 既知のバグ (→ 判明しているが修正しないことにした場合など) - 影響のある事前条件、事後条件 (→ メソッドが正しく動作するための前提について) - - 並行性 (→  マルチスレッドでアクセスされた場合の動作について) + - 並行性 (→ マルチスレッドでアクセスされた場合の動作について) - 該当メソッドの使用例やサンプルコード -- TODO コメント - 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。 - (Eclipse の TODO コメント形式を採用) - 例) +- TODO コメント\ + 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。\ + (Eclipse の TODO コメント形式を採用)\ + 例) ```java //TODO:ワークフローの仕様決定待ち 関連チケット#12345 @@ -2385,7 +2386,7 @@ Java では 3 種類のコメントが使える。javadoc コメントは`/**` Java8 で追加された Stream API での記述は、可読性も高く、簡潔に書けますが、パフォーマンス・性能面で注意が必要な場合があります。 -List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。 +List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。\ 以下に処理例と計測結果を記載します。 - 拡張 for 文 @@ -2420,14 +2421,14 @@ List の処理を行う際、拡張 for 文で処理する場合は Iterator イ | 1 億件 | 949 | 1,026 | | 2 億件 | 1,822 | 2,081 | -小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。 +小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。\ また、Stream API は並列処理(スレッド処理)の機能をサポートしていますので、利用できる場合は並列処理も含めての検証が必要です。 ## ラムダ式・メソッド参照・コンストラクタ参照 -Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。 +Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。\ 積極的な利用を推奨します。 以下に Comparator を生成した場合の計測結果を記載します。 @@ -2495,8 +2496,8 @@ Java8 で追加されたラムダ式・メソッド参照・コンストラク ### 文字列連結(繰り返し) -文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。 -繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。 +文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。\ +繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。\ また、コレクション要素の結合であれば`String#join`が利用できます。 以下に処理例と計測結果を記載します。 @@ -2601,7 +2602,7 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B 20 return ``` -`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。 +`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。\ `StringBuilder`を利用した場合は最適化はされず、記述した通りの処理が行われます。 計測した場合、下記のようになります。 @@ -2617,8 +2618,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B ## List の種類 -`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、 -`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。 +`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、\ +`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。\ `RandomAccess`ではない`List`は、`List#get`などインデックスを利用するような操作のパフォーマンスが低いので注意してください。 以下に処理例と計測結果を記載します。 @@ -2658,13 +2659,13 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B | 100 万件 | 1 | (30 秒以上) | 0(計測不能) | 4 | 0(計測不能) | 4 | | 1,000 万件 | 16 | (30 秒以上) | 8 | 45 | 6 | 44 | -ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、 -ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。 +ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、\ +ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。\ `List#get`での処理をすべて禁止することはできませんが、高いパフォーマンスが求められる場合は`List`の種類にも注目してみてください。 ## BigDecimal の ZERO との比較 -BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。 +BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。\ `compareTo`を利用して`BigDecimal.ZERO`と比較しても同じことができますが、`signum`を利用したほうが効率的です。 以下に処理例と計測結果を記載します。 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_8.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_8.md" index ff94413f..88d5d76b 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_for_8.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_8.md" @@ -10,8 +10,8 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに @@ -98,8 +98,8 @@ head: ## クラス -- クラス名は単語の先頭を大文字にする - 良い例: +- クラス名は単語の先頭を大文字にする\ + 良い例: ```java public class Entry { @@ -117,8 +117,8 @@ head: - コンストラクタと同じ名前のメソッドはつくらない -- メソッド名は区切りのみ大文字にする - 良い例: +- メソッド名は区切りのみ大文字にする\ + 良い例: ```java public String getName() { @@ -137,8 +137,8 @@ head: } ``` -- 変換メソッド名は「"`to`"+オブジェクト名」にする - 良い例: +- 変換メソッド名は「"`to`"+オブジェクト名」にする\ + 良い例: ```java public String toString() { @@ -150,8 +150,8 @@ head: public String string() { ``` -- ゲッターメソッド名は「"`get`"+属性名」にする - 型が`boolean`の場合は「"`is`"+属性名」にする +- ゲッターメソッド名は「"`get`"+属性名」にする\ + 型が`boolean`の場合は「"`is`"+属性名」にする - セッターメソッド名は「"`set`"+属性名」にする - `boolean`変数を返すメソッド名は`true`/`false`の状態がわかるようにする @@ -169,9 +169,9 @@ head: ## 引数 -- メソッドのパラメータ名とインスタンス変数名を一緒にしない - ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。 - アンダースコア `_` をつけての区別は原則禁止とする。 +- メソッドのパラメータ名とインスタンス変数名を一緒にしない\ + ただし、アクセサメソッドやコンストラクタなど、統合開発環境の機能により自動生成するものに関しては可とする。\ + アンダースコア `_` をつけての区別は原則禁止とする。 良い例: @@ -235,8 +235,8 @@ head: ## ローカル変数 -- スコープが狭い変数名は省略した名前でもよい - 良い例: +- スコープが狭い変数名は省略した名前でもよい\ + 良い例: ```java if (・・・) { @@ -293,8 +293,8 @@ head: ## 全般 -- 原則としてオブジェクトの参照にはインターフェースを利用する - オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 +- 原則としてオブジェクトの参照にはインターフェースを利用する\ + オブジェクトを参照する際は、そのオブジェクトの実装クラスを用いて宣言できるが、実装クラスに適切なインターフェースが存在している場合は、必ずインターフェースを用いて宣言すること。 良い例: @@ -310,15 +310,15 @@ head: HashMap map = new HashMap<>(); ``` -- 推奨されない API を使用しない - アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 +- 推奨されない API を使用しない\ + アノテーション`@Deprecated`で指定されたメソッドは利用しないこと。 - 使われないコードは書かない - 宣言は適切な権限で行うこと(`public`, `protected`, `private`) -- `final` を適切に利用する - 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 +- `final` を適切に利用する\ + 継承されないクラス、オーバーライドされないメソッド、値の変わらない変数(つまり定数)等、変化のないもの/変化させたくないものについては`final` で宣言する。 良い例: @@ -345,8 +345,8 @@ head: - インデントは空白文字 4 文字分の Tab を使用する - 長すぎる行は避ける -- `{` の後にステートメントを記述しない - 良い例: +- `{` の後にステートメントを記述しない\ + 良い例: ```java if (s == null) { @@ -360,8 +360,8 @@ head: if (s == null) {return 0;} ``` -- 1 行に 2 つ以上のステートメントを記述しない - 悪い例: +- 1 行に 2 つ以上のステートメントを記述しない\ + 悪い例: ```java } catch (Exception e) { @@ -369,8 +369,8 @@ head: } ``` -- カンマの後には空白文字を - 良い例: +- カンマの後には空白文字を\ + 良い例: ```java process(x, y, z); @@ -382,8 +382,8 @@ head: process(x,y,z); ``` -- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する - 良い例: +- 代入演算子( `=` , `+=` , `-=` , …)の前後には空白文字を挿入する\ + 良い例: ```java int a = x; @@ -397,8 +397,8 @@ head: a+= 10; ``` -- for 文内のセミコロンの後には空白文字を挿入する - 良い例: +- for 文内のセミコロンの後には空白文字を挿入する\ + 良い例: ```java for (int i = 0; i < array.length; i++) { @@ -414,8 +414,8 @@ head: } ``` -- `++` や `--` とオペランドの間には空白文字を入れない - 良い例: +- `++` や `--` とオペランドの間には空白文字を入れない\ + 良い例: ```java i++; @@ -431,8 +431,8 @@ head: - 論理演算子( `||` 、`&&`)の前後には空白文字を挿入する - 関係演算子( `<` 、 `>` 、 `>=` 、 `<=`、`==`、 `!=` )の前後には空白文字を挿入する - 算術演算子( `+` 、 `-` 、 `*` 、 `/` 、 `%` )の前後には空白文字を挿入する -- return 文ではカッコを使わない - 良い例: +- return 文ではカッコを使わない\ + 良い例: ```java int answer = (a + b + c) * d; @@ -459,8 +459,8 @@ head: if (hasStock == true) ``` -- 不等号の向きは左向き( `<` 、 `<=` )にする - 良い例: +- 不等号の向きは左向き( `<` 、 `<=` )にする\ + 良い例: ```java if (from <= x && x <= to) { @@ -474,14 +474,14 @@ head: ## コメント -- ファイルの先頭への Copyright の表記について - ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。 +- ファイルの先頭への Copyright の表記について\ + ソースのファイルヘッダにコピーライト標記は法的拘束力がないため、不要とする。\ ただし、顧客からの要求があった場合を除く。 - Javadoc コメントには、少なくとも author と version(クラス)、param と return と exception(メソッド)を記述する - 今後もバージョンアップのリリースが予定されているソースでは、上記に加えて since(バージョン)を記述する - `@Override`のあるメソッドでは、上記に加えて`{@Inherit}`を記述する -- Javadoc  クラスヘッダコメントのフォーマットは以下の通り +- Javadoc クラスヘッダコメントのフォーマットは以下の通り 良い例: @@ -494,8 +494,8 @@ head: */ ``` -- コメントは必要なものだけを簡潔に - 悪い例: +- コメントは必要なものだけを簡潔に\ + 悪い例: ```java /** @@ -514,12 +514,12 @@ head: - 不要なコメントは記載しない - コードからすぐわかること・冗長なコメント - - 名前の説明 - コメントではなくわかりやすい名前を付ける。 - - 別システムで管理している内容 - ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 - - コメントアウトされたコード - ソースコード管理システムで管理されている + - 名前の説明\ + コメントではなくわかりやすい名前を付ける。 + - 別システムで管理している内容\ + ソースコード管理システム、バグトラッキングシステムで管理している内容はソースコードにコメントで記載する必要はない。 + - コメントアウトされたコード\ + ソースコード管理システムで管理されている ## インポート @@ -531,7 +531,7 @@ head: import java.lang.String;//必要のない記述 ``` -- 原則として static インポートしない +- 原則として static インポートしない\ JUnit の作成やフレームワークとして static インポートが推奨されるような場合は利用してもよい - 原則としてオンデマンドのインポート宣言(type-import-on-demand declaration)(アスタリスク`*`によるインポート) は行わない @@ -544,8 +544,8 @@ head: ## コンストラクタ -- public 宣言していないクラスには`public`権限のコンストラクタを作らない - 良い例: +- public 宣言していないクラスには`public`権限のコンストラクタを作らない\ + 良い例: ```java class Entry { @@ -611,8 +611,8 @@ head: ## クラスメソッド -- クラスメソッドを利用するときは、クラス名を使って呼び出す - 良い例: +- クラスメソッドを利用するときは、クラス名を使って呼び出す\ + 良い例: ```java int comp = Integer.compare(x, y); @@ -627,8 +627,8 @@ head: ## 変数全般 -- 1 つのステートメントには 1 つの変数宣言 - 良い例: +- 1 つのステートメントには 1 つの変数宣言\ + 良い例: ```java /** 科目コード */ @@ -645,9 +645,9 @@ head: private String code, name, shortName; ``` -- リテラルは使用しない - リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。 - 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 +- リテラルは使用しない\ + リテラルとは、コード中に、表現が定数として直接現れており、記号やリストで表現することができないものを指す(数値、文字列両方含む 通称マジックナンバー)。コードの可読性・保守性の低下を防ぐために、リテラル定数(`static final` フィールド)を使用すること。\ + 例外:`-1`,`0`,`1` 等をカウント値としてループ処理等で使用するような場合 良い例: @@ -666,6 +666,7 @@ head: return mi * 1609.344; } ``` + - リテラル定数の名前はその値の意味を正しく表現したものにする 悪い例: @@ -688,15 +689,15 @@ head: private int sampleArray[] = new int[10]; ``` -- できるだけローカル変数を利用する - ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 +- できるだけローカル変数を利用する\ + ローカル変数で事足りるものをインスタンス変数として利用するなど、必要のないインスタンス変数を定義すると、パフォーマンスや可読性の低下やの大きな要因となる上、マルチスレッドを意識した際に不整合がおきる可能性があるので、インスタンス変数は必要性を充分に考慮してから使用すること。 - 定数は`final`で宣言する - ローカル変数とインスタンス変数を使いわける ## 定数 -- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する - `final` ではない `static` な定数は作成しない。 +- `public` で宣言するクラス変数とインスタンス変数は、定数のみとし、 `static final` で定義する\ + `final` ではない `static` な定数は作成しない。 良い例: @@ -791,8 +792,8 @@ head: ## クラス変数 -- `public static final` 宣言した配列を利用しない - ※「定数」を参照 +- `public static final` 宣言した配列を利用しない\ + ※「定数」を参照 - クラス変数にはクラス名を使用してアクセスすること @@ -809,12 +810,12 @@ head: BigDecimal b = a.ZERO; ``` -
+
## ローカル変数 -- ローカル変数は利用する直前で宣言する - 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 +- ローカル変数は利用する直前で宣言する\ + 行間の程度にもよるが、ある程度まとめて宣言するのは OK とする。 良い例: @@ -835,13 +836,13 @@ head: } ``` -- ローカル変数は安易に再利用しない - 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 +- ローカル変数は安易に再利用しない\ + 一度宣言したローカル変数を、複数の目的で安易に使いまわさないこと。ローカル変数は、役割ごとに新しいものを宣言して初期化することにより、コードの可読性・保守性の向上、及びコンパイラの最適化の促進をはかる。 ## 引数 -- メソッド引数への代入は行わない - 原則として`final`で宣言する。 +- メソッド引数への代入は行わない\ + 原則として`final`で宣言する。 良い例: @@ -853,8 +854,8 @@ head: ## 継承 -- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない - スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 +- スーパークラスのインスタンス変数をサブクラスでオーバーライドしない\ + スーパークラスと同じ名前のフィールドをサブクラスで宣言しないこと。 同じ名前のフィールドを宣言すると、スーパークラスのフィールドはサブクラスで宣言されたフィールドによって隠ぺいされてしまうので、他の人の混乱を招くことを防ぐため重複する名前は付けないこと。 悪い例: @@ -904,14 +905,14 @@ head: } ``` -- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない - スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 +- スーパークラスで private 宣言されているメソッドと同じ名前のメソッドをサブクラスで定義しない\ + スーパークラスにある private メソッドと同じ名前のメソッドをサブクラスで定義しないこと。private メソッドはオーバーライドされず全く別のメソッドとして扱われ、他の人の混乱を招き、バグにつながる恐れがある。 ## インナークラス -- 原則としてインナークラスは利用しない - 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。 - Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 +- 原則としてインナークラスは利用しない\ + 一つの java ファイルに複数のクラスを記載するのは NG とする。また無名クラスを利用するのも原則として NG とする。\ + Enum の定数固有メソッド実装(constant-specific method implementation)、Java8 のラムダ式は内部的にインナークラスとされるがこれらは許可する。 ## メンバー順序 @@ -995,8 +996,8 @@ head: return; ``` -- ステートメントが無い `{}` ブロックを利用しない - 悪い例: +- ステートメントが無い `{}` ブロックを利用しない\ + 悪い例: ```java //{}内の記述が無い @@ -1004,8 +1005,8 @@ head: } ``` -- `if` / `while` の条件式で `=` は利用しない - 良い例: +- `if` / `while` の条件式で `=` は利用しない\ + 良い例: ```java boolean a =// @@ -1031,8 +1032,8 @@ head: ``` - `for` と `while` の使い分けを意識する -- for 文を利用した繰り返し処理中でループ変数の値を変更しない - 悪い例: +- for 文を利用した繰り返し処理中でループ変数の値を変更しない\ + 悪い例: ```java String[] array = { /*・・・*/ }; @@ -1048,8 +1049,8 @@ head: ``` - for 文のカウンタは特別な事情がない限り、0 から始める -- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。 - 良い例: +- 配列やリストなどの全要素に対するループ処理は拡張 for 文を使用する。\ + 良い例: ```java for (int value : array) { @@ -1077,8 +1078,8 @@ head: ``` - 繰り返し処理中のオブジェクトの生成は最小限にする -- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する - 良い例: +- if 文と else 文の繰り返しや switch 文の利用はなるべく避け、オブジェクト指向の手法を利用する\ + 良い例: ```java CodingKind codingKind = toCodingKind(kind); @@ -1118,9 +1119,9 @@ head: } ``` -- 繰り返し処理の内部で `try` ブロックを利用しない - 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。 - ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 +- 繰り返し処理の内部で `try` ブロックを利用しない\ + 特に理由がない場合は繰り返し処理の外に`try`ブロックを記載する。\ + ただし、繰り返し処理内部で例外をキャッチし処理を行いたい場合は繰り返し処理の内部で`try`ブロックを利用してもよい。 良い例: @@ -1138,8 +1139,8 @@ head: ## 文字列操作 -- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する - 良い例: +- 文字列同士が同じ値かを比較するときは、`equals()`メソッドを利用する\ + 良い例: ```java String s1 = "text"; @@ -1159,8 +1160,8 @@ head: } ``` -- 文字列リテラルは`new` しない - 良い例: +- 文字列リテラルは`new` しない\ + 良い例: ```java String s = ""; @@ -1172,8 +1173,8 @@ head: String s = new String(); ``` -- 更新される文字列には`StringBuilder` クラスを利用する - 良い例: +- 更新される文字列には`StringBuilder` クラスを利用する\ + 良い例: ```java StringBuilder builder = new StringBuilder(); @@ -1193,14 +1194,15 @@ head: System.out.println(string); ``` -
- スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する +
+ + スレッドセーフ性が保証されていない箇所では`StringBuffer`クラスを利用する [※パフォーマンスについても記載しているので参考にしてください](#文字列連結) - 更新されない文字列には`String` クラスを利用する -- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する - 良い例: +- 文字列リテラルと定数を比較するときは、文字列リテラルの`equals()`メソッドを利用する\ + 良い例: ```java private static final String PROTOCOL_HTTP = "http"; @@ -1220,8 +1222,8 @@ head: } ``` -- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する - 良い例: +- プリミティブ型と`String` オブジェクトの変換には、変換用のメソッドを利用する\ + 良い例: ```java int i = 1000; @@ -1234,8 +1236,8 @@ head: ``` - 文字列の中に、ある文字が含まれているか調べるには、`contains()`メソッドを利用する -- システム依存記号( `\n` 、 `\r` など)は使用しない。 - 悪い例: +- システム依存記号( `\n` 、 `\r` など)は使用しない。\ + 悪い例: ```java String text = Arrays.stream(array) @@ -1244,10 +1246,10 @@ head: ## 数値 -- 誤差の無い計算をするときは、`BigDecimal` クラスを使う - 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 -- 数値の比較は精度に気をつける - 良い例: +- 誤差の無い計算をするときは、`BigDecimal` クラスを使う\ + 浮動小数点演算は科学技術計算に利用するもので、誤差が発生する。これに対して、クラス「`BigDecimal`」は、文字列で数値の計算を行うので、金額などの正確な計算に適している。`BigDecimal` ではインスタンス生成時に指定された桁数での精度が保証される。 +- 数値の比較は精度に気をつける\ + 良い例: ```java BigDecimal a = new BigDecimal("1"); @@ -1269,13 +1271,13 @@ head: ``` - 低精度なプリミティブ型にキャストしない -- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること - `toString()`を利用した場合、指数表記になることがあります。 +- `BigDecimal`を`String`変換する際は`toString()`ではなく`toPlainString()`を利用すること\ + `toString()`を利用した場合、指数表記になることがあります。 ## 日付 -- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う - 良い例: +- 日付の文字列のフォーマットには、`SimpleDateFormat`または`DateTimeFormatter`を使う\ + 良い例: ```java Date date = new Date(); @@ -1285,13 +1287,13 @@ head: ## 三項演算子 -- 入れ子の三項演算子の利用は禁止 - 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 +- 入れ子の三項演算子の利用は禁止\ + 可読性が悪くなるので三項演算子を入れ子で行うのは禁止。 ## コレクション -- Java2 以降のコレクションクラスを利用する - `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 +- Java2 以降のコレクションクラスを利用する\ + `Vector` クラス、`Hashtable` クラス、`Enumeration` 等は、特にこれらを利用する理由がなければ、インターフェースを統一する目的で、これらの代わりに`List`(`ArrayList` クラス)、`Map`(`HashMap` クラス)、`Iterator` を使用すること。`List` などのインターフェースを利用することで JDK1.2 で整理されたわかりやすいメソッドを利用でき、また、インターフェースの特性から呼び出し元を変更せずに実装クラスを変更することができる。 - 特定の型のオブジェクトだけを受け入れるコレクションクラスを利用する 良い例: @@ -1300,13 +1302,13 @@ head: List> list = new ArrayList<>(); ``` -- `List`のソートは`List.sort()`を利用する - `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。 - Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 -- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する - Java8 で追加されたメソッド。 - 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。 - 具体的には下記のメソッドを利用しないこと。 +- `List`のソートは`List.sort()`を利用する\ + `List`クラスの要素をソートする際は Java8 で追加された`List.sort()`を利用すること。\ + Java 7 以前で利用されていた`Collections.sort()`は利用しないこと。 +- `Collection.forEach()`は利用しない。拡張 for 文の利用を検討する\ + Java8 で追加されたメソッド。\ + 拡張 for 文を利用したほうが多くの場合でデバッグに有利であり、可読性においても`forEach`の優位性は少ないため、`forEach`は原則利用しない。拡張 for 文を利用する。\ + 具体的には下記のメソッドを利用しないこと。 - `Collection#forEach` - `Set#forEach` - `List#forEach` @@ -1329,8 +1331,8 @@ head: }); ``` - ただし、メソッド参照で処理できる場合は`forEach`を利用する。 - (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) + ただし、メソッド参照で処理できる場合は`forEach`を利用する。\ + (デバッグのデメリットがほとんどなく、他と比較して処理効率が良いため) 良い例: @@ -1348,7 +1350,7 @@ head: ## ラムダ式・メソッド参照・コンストラクタ参照 -- ラムダ式が利用できる箇所はラムダ式を利用してよい +- ラムダ式が利用できる箇所はラムダ式を利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#ラムダ式メソッド参照コンストラクタ参照-1) - ただし、メソッド参照・コンストラクタ参照が利用できる場合はメソッド参照・コンストラクタ参照を利用する @@ -1390,7 +1392,7 @@ head: (String s1, String s2) -> s1 + "=" + s2 ``` -- 原則ラムダ式内の行数は 1 行とする +- 原則ラムダ式内の行数は 1 行とする\ 複数行で利用したい場合は、`private`メソッドを作成しメソッド参照を利用する 良い例: @@ -1437,15 +1439,15 @@ head: ## 実質的 final(effectively final) -- 実質的 final を利用する +- 実質的 final を利用する\ 変数宣言に`final`を記載しなくてよい。 ## Stream API -- 利用してよい +- 利用してよい\ [※パフォーマンスについても記載しているので参考にしてください](#stream-api-2) -- 並列ストリームは利用しないこと - 悪い例: +- 並列ストリームは利用しないこと\ + 悪い例: ```java Stream s = list.parallelStream(); @@ -1477,10 +1479,10 @@ head: ``` - インデントは統合開発環境の提供するフォーマッタに合わせる -- 中間処理の数は 3 つ(3 行)程度までを推奨する - 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 -- コメントは、原則として処理中には記載しない - 難解になってしまった場合のみ処理中の記載を認める +- 中間処理の数は 3 つ(3 行)程度までを推奨する\ + 中間処理の記述が多くなると可読性も悪くなり、デバッグも難しくなるため、3 行程度を目安にロジックを検討すること。 +- コメントは、原則として処理中には記載しない\ + 難解になってしまった場合のみ処理中の記載を認める 良い例: @@ -1510,9 +1512,9 @@ head: .forEach(this::proc); ``` -- Stream は極力変数代入しないこと - Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。 - 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 +- Stream は極力変数代入しないこと\ + Stream は中間処理、末端処理を行うと使用済みとなり、以降同じインスタンスは利用できない。\ + 変数代入はほとんどの場合意味をなさず、むしろミスの元となるため極力変数代入はしないこと。 良い例: @@ -1539,8 +1541,8 @@ head: ## Optional -- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと - Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 +- Optional は同メソッド内で値を取り出す場合は極力変数代入しないこと\ + Optional とその値の変数は同じものを示す名前となり、同じ意味の変数名が複数現れることで可読性が下がるため、Optional の変数代入は行わないこととする。 良い例: @@ -1556,7 +1558,7 @@ head: Employee employee = employeeOpt.orElseThrow(IllegalArgumentException::new); ``` -
+
直接、値を取り出すことなくOptionalでのみ扱う場合はOptionalを変数代入してもよい。 良い例: @@ -1604,8 +1606,8 @@ head: } ``` -- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する - `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 +- リソース解放を必要とするクラスを作成する場合は`AutoCloseable`を`implements`する\ + `AutoCloseable`を`implements`することで try-with-resources 文が利用できるようになります。 ## 例外 @@ -1647,19 +1649,19 @@ head: ## よいコメントの鉄則 -- コードを明確化するコメントを書く +- コードを明確化するコメントを書く\ コードにコメントを書く理由は、自分自身、一緒に仕事をしている人、後に関わる開発者にとってコードをより理解しやすいものにするためである。 -- コメント化する価値がないプログラムならば、実行するに値しない +- コメント化する価値がないプログラムならば、実行するに値しない\ 有用な格言。コメントは必須。 -- 過剰な装飾は使わない (例:見出し状のコメント) +- 過剰な装飾は使わない (例:見出し状のコメント)\ 1960 年代から 1970 年代の典型的な COBOL プログラマにはアスタリスク( `*` )でコメントを囲った箱を書く習慣があった。彼らの芸術的な主張を表わしているのかもしれないが、率直に言えばそれは製品に加わるちょっとした価値に比べれば大きな時間の無駄である。かわいいコードではなくきれいなコードを書くはずである。さらに、コードを表示するディスプレイや印刷するプリントに使われるフォントはプロポーショナルだったりそうでなかったりして、箱をきれいに整列させることは難しい。 -- コメントはシンプルに +- コメントはシンプルに\ かつて見たもっとも最良のコメントは、シンプルな要点をまとめた注釈であった。なにも本を書く必要はなく、他の人がコードを理解するに十分な情報を提供するだけでよいのである。 -- コードを書く前に先にコメントを記述する +- コードを書く前に先にコメントを記述する\ コードをコメント化する最良の方法は、コードを書く前にコメントを書くことである。それが、コードを書く前にコードがどのように動作するかについて考えるよい機会となり、コメントの存在を保障することにもつながる。少なくともコードを書いた時にコメントすべきである。コメントによってコードが理解しやすくなることで、コードの開発中にアドバンテージを得ることができる。コードにコメントを書く時間を費やせば、それによって得られるものがある。 -- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない - 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか? - どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 +- コメントには、なぜそうなのかを書く。コードを読めば分かることを書かない\ + 基本的に、コードの一部分を見ればそれが何かを理解することはできる。例えば、以下のコードを見て、$1000 以上の注文については 5%ディスカウントされることは理解できる。なぜそうなのか?大きな注文ではディスカウントがつきものだというビジネスルールがあるのだろうか?大きな注文に時間限定サービスがあるのか、それともずっとサービスがあるのか?これを書いたプログラマの気前がよかったのか?\ + どこかソースコード中か別な文書にコメントされていない限り、それがなぜなのかを知ることはできない。 ```java if (grandTotal >= 1000.00) { @@ -1671,13 +1673,13 @@ head: - 副作用のある処理の場合は、その内容 (→ メソッドの引数オブジェクトがメソッド内で変更されるケースなど) - 既知のバグ (→ 判明しているが修正しないことにした場合など) - 影響のある事前条件、事後条件 (→ メソッドが正しく動作するための前提について) - - 並行性 (→  マルチスレッドでアクセスされた場合の動作について) + - 並行性 (→ マルチスレッドでアクセスされた場合の動作について) - 該当メソッドの使用例やサンプルコード -- TODO コメント - 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。 - (Eclipse の TODO コメント形式を採用) - 例) +- TODO コメント\ + 設計者確認待ち、共通処理の作成待ちなどの理由により、実装時に TODO がある場合、下記のようにコメントを記述する。\ + (Eclipse の TODO コメント形式を採用)\ + 例) ```java //TODO:ワークフローの仕様決定待ち 関連チケット#12345 @@ -1709,7 +1711,7 @@ Java では 3 種類のコメントが使える。javadoc コメントは`/**` Java8 で追加された Stream API での記述は、可読性も高く、簡潔に書けますが、パフォーマンス・性能面で注意が必要な場合があります。 -List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。 +List の処理を行う際、拡張 for 文で処理する場合は Iterator インスタンスが 1 つだけ生成されますが、Stream API で処理する場合、最初の Stream インスタンスに加え、各中間処理ごとにも Stream インスタンスが生成され、その分の性能劣化が懸念されます。\ 以下に処理例と計測結果を記載します。 - 拡張 for 文 @@ -1744,14 +1746,14 @@ List の処理を行う際、拡張 for 文で処理する場合は Iterator イ | 1 億件 | 949 | 1,026 | | 2 億件 | 1,822 | 2,081 | -小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。 +小中規模の処理量であれば考慮するほどの性能差はありませんが、大量の処理が見込まれる場合は考慮が必要です。\ また、Stream API は並列処理(スレッド処理)の機能をサポートしていますので、利用できる場合は並列処理も含めての検証が必要です。 ## ラムダ式・メソッド参照・コンストラクタ参照 -Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。 +Java8 で追加されたラムダ式・メソッド参照・コンストラクタ参照は、匿名クラスを利用するよりも効率的です。\ 積極的な利用を推奨します。 以下に Comparator を生成した場合の計測結果を記載します。 @@ -1819,8 +1821,8 @@ Java8 で追加されたラムダ式・メソッド参照・コンストラク ### 文字列連結(繰り返し) -文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。 -繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。 +文字列連結を繰り返し処理中で行う際、`+`演算子で処理することはアンチパターンとして知られています。\ +繰り返し処理中の文字列連結は、 `StringBuilder`、 `StringJoiner`、 `StringBuffer` を利用します。\ また、コレクション要素の結合であれば`String#join`が利用できます。 以下に処理例と計測結果を記載します。 @@ -1925,7 +1927,7 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B 20 return ``` -`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。 +`+`演算子を利用した場合コンパイル時に最適化され、文字列`"A"`と`"B"`をあらかじめ結合して class が作成されます。\ `StringBuilder`を利用した場合は最適化はされず、記述した通りの処理が行われます。 計測した場合、下記のようになります。 @@ -1941,8 +1943,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B ## List の種類 -`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、 -`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。 +`List`には`ArrayList`のような`RandomAccess`を implements した、ランダムアクセスをサポートしているクラスと、\ +`LinkedList`のようなランダムアクセスをサポートしていない(シーケンシャルアクセス)クラスが存在します。\ `RandomAccess`ではない`List`は、`List#get`などインデックスを利用するような操作のパフォーマンスが低いので注意してください。 以下に処理例と計測結果を記載します。 @@ -1982,8 +1984,8 @@ private static final String CONST_AB = new StringBuilder(CONST_A).append(CONST_B | 100 万件 | 1 | (30 秒以上) | 0(計測不能) | 4 | 0(計測不能) | 4 | | 1,000 万件 | 16 | (30 秒以上) | 8 | 45 | 6 | 44 | -ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、 -ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。 +ランダムアクセスをサポートしている`List`がシーケンシャルアクセス(iterator を利用した処理など)で遅いということはないので、\ +ループの処理は拡張 for 文等、Iterator によるループで記述するのが無難です。\ `List#get`での処理をすべて禁止することはできませんが、高いパフォーマンスが求められる場合は`List`の種類にも注目してみてください。 ## String から Integer・Long への変換 @@ -2002,11 +2004,11 @@ String s = "1"; Integer value = new Integer(s); ``` -これらの違いは、 -`new Integer(s)`とした場合、必ず Integer インスタンスが生成されますが、 +これらの違いは、\ +`new Integer(s)`とした場合、必ず Integer インスタンスが生成されますが、\ `Integer.valueOf(s)`とした場合は -128 から 127 の間の数値であればキャッシュから取り出すためインスタンスを生成しません。 -このため、前者の`Integer#valueOf(String)`を利用した記述のほうが効率的です。 +このため、前者の`Integer#valueOf(String)`を利用した記述のほうが効率的です。\ `Long#valueOf(String)`も同様です。 性能差が少ないため、ほとんど問題にはなりませんが、FindBugs 等、静的解析で検出される問題のため、理解が必要です。 @@ -2034,7 +2036,7 @@ String s = "1"; int value = new Integer(s);//生成したIntegerインスタンスをオートボクシングでintにcastしている ``` -「オートボクシング」の説明に記載した通り、性能に差が出るだけでなく、 +「オートボクシング」の説明に記載した通り、性能に差が出るだけでなく、\ 記述から明らかにミスであることが解るため、FindBugs 等、静的解析で検出されるコードです。 `long`への変換の場合は`Long#parseLong(String)`を利用します @@ -2050,7 +2052,7 @@ int value = new Integer(s);//生成したIntegerインスタンスをオート ## BigDecimal の ZERO との比較 -BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。 +BigDecimal の正・負・ZERO の判定は`BigDecimal#signum`を利用します。\ `compareTo`を利用して`BigDecimal.ZERO`と比較しても同じことができますが、`signum`を利用したほうが効率的です。 以下に処理例と計測結果を記載します。 diff --git a/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md b/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md index db71d046..1ce946f0 100644 --- a/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md +++ b/documents/forOpenAPISpecification/OpenAPI_Specification_2.0.md @@ -108,6 +108,7 @@ description: "何かしらの説明" - account_type - register_at ``` + - YAML は項目定義がネストすることで縦長な定義になりやすい。情報密度を上げるために配列リテラルを推奨する ## 改行の表現 @@ -297,8 +298,8 @@ schemes: Swagger では、次の認証タイプを記載できる([詳細](https://swagger.io/docs/specification/2-0/authentication/))。 1. ベーシック認証 -1. API キー(リクエストヘッダ, クエリパラメータ) -1. OAuth2 +2. API キー(リクエストヘッダ, クエリパラメータ) +3. OAuth2 もし、認証が必須であれば記載する。全ての Web API で未認証を受け入れる場合は記載しない。認証の要否が API ごとに異なる場合は、各 API 側で `security: []` と記載しして上書き定義する必要がある。 @@ -522,6 +523,7 @@ URL に紐づく HTTP メソッドで、1 つの操作を定義します。 type: string ... ``` + - モデル名は、 `{HTTPメソッド名}{物理名}` の PascalCase で記載する - 例: PutUserAccount、PostUserAccount, PatchUserAccount @@ -957,7 +959,7 @@ Swagger 定義で以下の変更を行う場合は、利用するコード生成 # 推奨ツール -[本当に使ってよかった OpenAPI (Swagger) ツール ](https://future-architect.github.io/articles/20191008/) にあるように、様々なツールで開発ができる。VS Code を用いる場合は以下のプラグインを推奨する。 +[本当に使ってよかった OpenAPI (Swagger) ツール](https://future-architect.github.io/articles/20191008/) にあるように、様々なツールで開発ができる。VS Code を用いる場合は以下のプラグインを推奨する。 - [YAML](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) - [Swagger Viewer](https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer) diff --git a/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md b/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md index 1c411be5..1e5d7b26 100644 --- a/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md +++ b/documents/forOpenAPISpecification/OpenAPI_Specification_3.0.3.md @@ -10,8 +10,8 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに @@ -109,6 +109,7 @@ description: "何かしらの説明" - account_type - register_at ``` + - YAML は項目定義がネストすることで縦長な定義になりやすい。情報密度を上げるために配列リテラルを推奨する ## 改行の表現 @@ -779,7 +780,7 @@ components: ... ``` -正常系のレスポンスの例としてはファイルアップロード・ダウンロードのレスポンスなどが該当する。 +正常系のレスポンスの例としてはファイルアップロード・ダウンロードのレスポンスなどが該当する。\ 個別のアプリケーション要件でブレが少なく、複数のエンドポイントで用いられる場合に定義する。オブジェクトのスキーマは、`schemas` に切り出して定義し、コード生成ツールのために型情報を付与させる。 良い例: diff --git "a/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210Oracle\357\274\211.md" "b/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210Oracle\357\274\211.md" index 480f2e35..fa0d8d96 100644 --- "a/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210Oracle\357\274\211.md" +++ "b/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210Oracle\357\274\211.md" @@ -10,15 +10,15 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに ## 前提条件 -本書は、SQL コーディング規約についてまとめたものである。 +本書は、SQL コーディング規約についてまとめたものである。\ 今回 RDBMS として採用する Oracle での SQL の使用を前提に記述している。 # SQL コーティング規約(可読性・管理性) @@ -48,17 +48,17 @@ head: SQL 中に記述するエイリアス名など単語の短縮について示す。 -1. 外来語に関しては、原語の短縮形を使用する。短縮形が存在しない場合には、母音を抜かして表記する。 +1. 外来語に関しては、原語の短縮形を使用する。短縮形が存在しない場合には、母音を抜かして表記する。\ 例) corporation → corp / computer → cmptr -2. ローマ字の短縮は、単語の区切れの頭文字、または母音を抜かした子音字等を利用する。 +2. ローマ字の短縮は、単語の区切れの頭文字、または母音を抜かした子音字等を利用する。\ 例) nichijo → nchj - カラムには必ずテーブルエイリアスを付与する -- テーブルのエイリアスは必ず付与すること。 - 必要ない場合(単一テーブルへの SELECT 等)も必ず付与すること - また、テーブルのエイリアス名は同 SQL 文の中で重複しないように命名すること。 - (副問い合わせで利用したエイリアス名をメインの SQL 中のエイリアス名に利用しない。など) +- テーブルのエイリアスは必ず付与すること。\ + 必要ない場合(単一テーブルへの SELECT 等)も必ず付与すること\ + また、テーブルのエイリアス名は同 SQL 文の中で重複しないように命名すること。\ + (副問い合わせで利用したエイリアス名をメインの SQL 中のエイリアス名に利用しない。など) ## 文字コード @@ -70,14 +70,14 @@ SQL ファイルの文字コード(エンコーディング)は Java ソー ## SQL 文の整形 -DML 文の節に対する予約語は左揃えにする。 -項目ごとに改行を入れ、項目の前にはインデントを挿入する。カンマは項目の前へ記入する。 -Java ソースファイルのようにファイルの先頭にコメント行を入れると DB 分析作業に支障があるため禁止とする。 +DML 文の節に対する予約語は左揃えにする。\ +項目ごとに改行を入れ、項目の前にはインデントを挿入する。カンマは項目の前へ記入する。\ +Java ソースファイルのようにファイルの先頭にコメント行を入れると DB 分析作業に支障があるため禁止とする。\ よって SQL ファイルの先頭は必ず`SELECT`、`UPDATE`、`INSERT`、`DELETE`、`MERGE`の何れかになる。 -物理カラム名、テーブル名に対応する論理名を入れる場合、その後ろに単数行コメント(`-- `)にて記述する。 -SQL 内に挿入する単数行コメントは、`/*(半角スペース)コメント本文(半角スペース)*/` で行う。 -`,`(カンマ)と`AND`については各行の先頭に記述する。(以下の例を参照のこと) +物理カラム名、テーブル名に対応する論理名を入れる場合、その後ろに単数行コメント(`-- `)にて記述する。\ +SQL 内に挿入する単数行コメントは、`/*(半角スペース)コメント本文(半角スペース)*/` で行う。\ +`,`(カンマ)と`AND`については各行の先頭に記述する。(以下の例を参照のこと)\ SQL フレームワークで実行する SQL の場合、SQL ステートメントの終わりを示す`;`(セミコロン)は記述しない。 良い例: @@ -220,7 +220,7 @@ CASE END ``` -`CASE`、`WHEN`、`THEN`、`ELSE`の後に改行を挿入すること。 +`CASE`、`WHEN`、`THEN`、`ELSE`の後に改行を挿入すること。\ `CASE`の後、`END`の前までは 1 インデント挿入すること。 ### IN 句 @@ -233,9 +233,9 @@ END ### 改行位置 -SELECT 句、ORDER BY 句、GROUP BY 句等は最初に出現するカラムとカラムの区切りのカンマ前に改行を入れること。 -SELECT の FROM 句の最初に出現するテーブルと結合テーブルの区切りのカンマ前に改行を入れること。 -WHERE 句、MERGE の ON 句の各条件文の(AND や OR の)前に改行を入れること。 +SELECT 句、ORDER BY 句、GROUP BY 句等は最初に出現するカラムとカラムの区切りのカンマ前に改行を入れること。\ +SELECT の FROM 句の最初に出現するテーブルと結合テーブルの区切りのカンマ前に改行を入れること。\ +WHERE 句、MERGE の ON 句の各条件文の(AND や OR の)前に改行を入れること。\ 命令句の後は、ヒント句が挿入できるように改行すること。 良い例: @@ -257,7 +257,7 @@ ORDER BY ### WITH 句 -WITH の前後に改行を挿入すること +WITH の前後に改行を挿入すること\ また、インデントは下記のように記述すること 良い例: @@ -311,7 +311,7 @@ FETCH NEXT 5 ROWS ONLY ### HINT 句 -HINT 句は独立した行で記載すること +HINT 句は独立した行で記載すること\ HINT 内容にはインデントを付けること 良い例: @@ -332,8 +332,8 @@ WHERE - 修正コメント - (修正コメントが必要な場合、) - 処理追加の際、追加行の 1 行目の前と最終行の次の行にコメントを入れる。単一行の場合は、同一行の最後にコメントをつける。 + (修正コメントが必要な場合、)\ + 処理追加の際、追加行の 1 行目の前と最終行の次の行にコメントを入れる。単一行の場合は、同一行の最後にコメントをつける。 良い例: @@ -349,8 +349,8 @@ WHERE - 複数行コメント - 「 `/*` `*/` 」を使用する。下記に例を示す。 - なお、前述で触れたとおり、SQL ファイルの先頭にコメントを記述することは禁止とする。 + 「 `/*` `*/` 」を使用する。下記に例を示す。\ + なお、前述で触れたとおり、SQL ファイルの先頭にコメントを記述することは禁止とする。 良い例: @@ -367,19 +367,19 @@ WHERE - 複数行コメントアウト - 複数行をコメントアウトする場合は、各行を「`--`」でコメントアウトする。 - 「 `/*` `*/` 」を使用すると、その中に「 `/*` `*/` 」が存在した場合、コメントアウトが途中で切れてしまう恐れがあるため、 - 使用しない。 + 複数行をコメントアウトする場合は、各行を「`--`」でコメントアウトする。\ + 「 `/*` `*/` 」を使用すると、その中に「 `/*` `*/` 」が存在した場合、コメントアウトが途中で切れてしまう恐れがあるため、\ + 使用しない。 - 論理名の記載 - `SELECT`・`INSERT`・`UPDATE`・`MERGE`のカラム名記述箇所には単数行コメントでカラムの論理名を記載する。 - `SELECT`・`INSERT`・`UPDATE`・`DELETE`・`MERGE`のテーブル名記述箇所には単数行コメントでテーブルの論理名を記載する。 - 論理名は ERD 等で定義された論理名と必ず一致させること。 + `SELECT`・`INSERT`・`UPDATE`・`MERGE`のカラム名記述箇所には単数行コメントでカラムの論理名を記載する。\ + `SELECT`・`INSERT`・`UPDATE`・`DELETE`・`MERGE`のテーブル名記述箇所には単数行コメントでテーブルの論理名を記載する。\ + 論理名は ERD 等で定義された論理名と必ず一致させること。 ## 外部結合 -結合方法は ANSI 形式(~`outer join` ~)ではなく Oracle 形式`(+)`を使用する。 +結合方法は ANSI 形式(~`outer join` ~)ではなく Oracle 形式`(+)`を使用する。\ 原則として`(+)`は条件文の右にくるカラムに付与する。 良い例: @@ -408,8 +408,8 @@ T1.COL1 = T2.COL2(+) ## EXISTS 句 -EXISTS 句を記載する際、サブクエリになる SELECT 句の指定は定数「`1`」とする。 -「`*`」(ワイルドカード)や「`'X'`」は統一の観点から利用しない。 +EXISTS 句を記載する際、サブクエリになる SELECT 句の指定は定数「`1`」とする。\ +「`*`」(ワイルドカード)や「`'X'`」は統一の観点から利用しない。\ また「`*`」(ワイルドカード)についてはパフォーマンスの観点からも禁止とする。 良い例: @@ -428,14 +428,14 @@ WHERE ## AS 句 -トップレベルの SELECT 句には必ず`AS`句を記載し別名を付ける。 -同一の名前であっても AS 句を付与する。 +トップレベルの SELECT 句には必ず`AS`句を記載し別名を付ける。\ +同一の名前であっても AS 句を付与する。\ また、「`AS`」は省略可能であるが、省略はしないこと。 ## WHERE 句 -- 論理名の記載 - WHERE 句でカラムと式を比較する際は左辺がカラムになるように記載すること。 +- 論理名の記載\ + WHERE 句でカラムと式を比較する際は左辺がカラムになるように記載すること。 良い例: @@ -445,9 +445,9 @@ WHERE AND TBL.AMOUNT2 > TBL.AMOUNT3 + TBL.AMOUNT4 ``` -- 条件式の順序 - 原則として、WHERE 句で条件式を列挙する際、下記の順序を守ること。 - 1. テーブル単位にまとめて順番に記述する +- 条件式の順序\ + 原則として、WHERE 句で条件式を列挙する際、下記の順序を守ること。 + 1. テーブル単位にまとめて順番に記述する\ この際、テーブルの順序は FROM 句に記述した順序に準ずること。 2. 1.のテーブル単位の中で絞り込み条件をまず記述し、その後結合条件を記述する。 @@ -478,7 +478,7 @@ WHERE ## COUNT 文 -レコード数を数える COUNT 文の記述は`COUNT(*)`と記述する。 +レコード数を数える COUNT 文の記述は`COUNT(*)`と記述する。\ `COUNT(1)`・`COUNT('X')` ・`COUNT(KEY1)`という記載は NG。 # SQL コーディング規約(パフォーマンス性) @@ -492,8 +492,8 @@ WHERE - 中間一致、後方一致検索はインデックスを利用できないため避ける - 検索条件で`=`(等号)を使用できる場合は必ず使用する - `A=1 or A=2`とする方が`A>0 and A<3`などと記述するのよりパフォーマンス上優位な場合が多い。 - これは A にインデックスがある場合、`=`であれば、インデックスが有効に使われるためである。 + `A=1 or A=2`とする方が`A>0 and A<3`などと記述するのよりパフォーマンス上優位な場合が多い。\ + これは A にインデックスがある場合、`=`であれば、インデックスが有効に使われるためである。 - 可能な限り検索条件にパーティションキーの値を指定する - 全列ワイルドカード「`*`」の使用はせず、カラム名を明記する @@ -549,8 +549,8 @@ WHERE 更新処理におけるコーディング規約を下記に示す。 -- 主キーの値の UPDATE は原則行わない。外部キーがあればエラーになる。 - 外部キーが無い場合でも、事実上、主キーの値を利用して、検索、更新する場合は、リンクが切れてしまう。 +- 主キーの値の UPDATE は原則行わない。外部キーがあればエラーになる。\ + 外部キーが無い場合でも、事実上、主キーの値を利用して、検索、更新する場合は、リンクが切れてしまう。 - パーティションキーの UPDATE は原則行わない。 - VIEW を使用するデータ更新は禁止。更新は実表に対して行う。 @@ -566,7 +566,7 @@ WITH 句の誤った使い方はパフォーマンスの劣化を招くため、 ## DISTINCT 句 -DISTINCT は、暗黙のソート処理が行われる可能性があるため性能劣化につながる。 +DISTINCT は、暗黙のソート処理が行われる可能性があるため性能劣化につながる。\ EXISTS 句の使用・代替を検討すること。 悪い例: @@ -604,13 +604,13 @@ WHERE ## IN 句 -IN 句は最大 1000 個まで指定できるが、200 個程度でも ORA エラーが発生するケースがある。 -また IN 句の少しだけ異なる SQL が大量に発行されると CPU 高騰やメモリ枯渇を招く。 +IN 句は最大 1000 個まで指定できるが、200 個程度でも ORA エラーが発生するケースがある。\ +また IN 句の少しだけ異なる SQL が大量に発行されると CPU 高騰やメモリ枯渇を招く。\ 従って 100 を超えるような長い IN 句は使用せず、一時表を利用して `IN (SELECT ・・・ FROM 一時表)`のように書き換える。 ## NOT IN 句 -原則`NOT IN(SELECT~)`は使用せずに、`NOT EXISTS (SELECT~)`を使用する。 +原則`NOT IN(SELECT~)`は使用せずに、`NOT EXISTS (SELECT~)`を使用する。\ `NOT IN`句は、内部的にソートマージの結合をすることでテーブルをフルスキャンする場合があるため、性能が悪化する可能性がある。 ## UNION 句 @@ -623,10 +623,10 @@ IN 句は最大 1000 個まで指定できるが、200 個程度でも ORA エ ## SELECT FOR UPDATE -- `SELECT FOR UPDATE`は`NO WAIT`または「`WAIT`秒数指定」を必ず付ける。 - `WAIT`指定なしの場合はロックが解除されてもプログラムに制御が返らないことがある。 - ※WAIT 秒数指定を行う際の秒数は各開発者で決めるのではなくプロジェクトで決定した方針に従うこと。 - また、SQL ライブラリを利用していて定数が記述できる場合は定数で記述すること。 +- `SELECT FOR UPDATE`は`NO WAIT`または「`WAIT`秒数指定」を必ず付ける。\ + `WAIT`指定なしの場合はロックが解除されてもプログラムに制御が返らないことがある。\ + ※WAIT 秒数指定を行う際の秒数は各開発者で決めるのではなくプロジェクトで決定した方針に従うこと。\ + また、SQL ライブラリを利用していて定数が記述できる場合は定数で記述すること。 - `SELECT FOR UPDATE`で複数行にロックをかける場合、同時実行されるとデットロックを起こす可能性があるため、1件のロックでない場合は`ORDER BY`を指定する。 ## 分析関数 diff --git "a/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210PostgreSQL\357\274\211.md" "b/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210PostgreSQL\357\274\211.md" index db551516..a5a56263 100644 --- "a/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210PostgreSQL\357\274\211.md" +++ "b/documents/forSQL/SQL\343\202\263\343\203\274\343\203\207\343\202\243\343\203\263\343\202\260\350\246\217\347\264\204\357\274\210PostgreSQL\357\274\211.md" @@ -10,15 +10,15 @@ head: -本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。 -ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。 +本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。\ +ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。\ また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。 # はじめに ## 前提条件 -本書は、SQL コーディング規約についてまとめたものである。 +本書は、SQL コーディング規約についてまとめたものである。\ 今回 RDBMS として採用する PostgreSQL での SQL の使用を前提に記述している。 # SQL コーティング規約(可読性・管理性) @@ -48,17 +48,17 @@ head: SQL 中に記述するエイリアス名など単語の短縮について示す。 -1. 外来語に関しては、原語の短縮形を使用する。短縮形が存在しない場合には、母音を抜かして表記する。 +1. 外来語に関しては、原語の短縮形を使用する。短縮形が存在しない場合には、母音を抜かして表記する。\ 例) corporation → corp / computer → cmptr -2. ローマ字の短縮は、単語の区切れの頭文字、または母音を抜かした子音字等を利用する。 +2. ローマ字の短縮は、単語の区切れの頭文字、または母音を抜かした子音字等を利用する。\ 例) nichijo → nchj - カラムには必ずテーブルエイリアスを付与する -- テーブルのエイリアスは必ず付与すること。 - 必要ない場合(単一テーブルへの SELECT 等)も必ず付与すること - また、テーブルのエイリアス名は同 SQL 文の中で重複しないように命名すること。 - (副問い合わせで利用したエイリアス名をメインの SQL 中のエイリアス名に利用しない。など) +- テーブルのエイリアスは必ず付与すること。\ + 必要ない場合(単一テーブルへの SELECT 等)も必ず付与すること\ + また、テーブルのエイリアス名は同 SQL 文の中で重複しないように命名すること。\ + (副問い合わせで利用したエイリアス名をメインの SQL 中のエイリアス名に利用しない。など) ## 文字コード @@ -70,14 +70,14 @@ SQL ファイルの文字コード(エンコーディング)は Java ソー ## SQL 文の整形 -DML 文の節に対する予約語は左揃えにする。 -項目ごとに改行を入れ、項目の前にはインデントを挿入する。カンマは項目の前へ記入する。 -Java ソースファイルのようにファイルの先頭にコメント行を入れると DB 分析作業に支障があるため禁止とする。 +DML 文の節に対する予約語は左揃えにする。\ +項目ごとに改行を入れ、項目の前にはインデントを挿入する。カンマは項目の前へ記入する。\ +Java ソースファイルのようにファイルの先頭にコメント行を入れると DB 分析作業に支障があるため禁止とする。\ よって SQL ファイルの先頭は必ず`select`、`update`、`insert`、`delete`の何れかになる。 -物理カラム名、テーブル名に対応する論理名を入れる場合、その後ろに単数行コメント(`-- `)にて記述する。 -SQL 内に挿入する単数行コメントは、`/*(半角スペース)コメント本文(半角スペース)*/` で行う。 -`,`(カンマ)と`AND`については各行の先頭に記述する。(以下の例を参照のこと) +物理カラム名、テーブル名に対応する論理名を入れる場合、その後ろに単数行コメント(`-- `)にて記述する。\ +SQL 内に挿入する単数行コメントは、`/*(半角スペース)コメント本文(半角スペース)*/` で行う。\ +`,`(カンマ)と`AND`については各行の先頭に記述する。(以下の例を参照のこと)\ SQL フレームワークで実行する SQL の場合、SQL ステートメントの終わりを示す`;`(セミコロン)は記述しない。 良い例: @@ -198,7 +198,7 @@ case end ``` -`case`、`when`、`then`、`else`の後に改行を挿入すること。 +`case`、`when`、`then`、`else`の後に改行を挿入すること。\ `case`の後、`end`の前までは 1 インデント挿入すること。 ### IN 句 @@ -211,9 +211,9 @@ end ### 改行位置 -select 句、order by 句、group by 句等は最初に出現するカラムとカラムの区切りのカンマ前に改行を入れること。 -select の from 句の最初に出現するテーブルと結合テーブルの区切りのカンマ前に改行を入れること。 -where 句の on 句の各条件文の(and や or の)前に改行を入れること。 +select 句、order by 句、group by 句等は最初に出現するカラムとカラムの区切りのカンマ前に改行を入れること。\ +select の from 句の最初に出現するテーブルと結合テーブルの区切りのカンマ前に改行を入れること。\ +where 句の on 句の各条件文の(and や or の)前に改行を入れること。\ 命令句の後は、ヒント句が挿入できるように改行すること。 良い例: @@ -235,7 +235,7 @@ order by ### WITH 句 -with の前後に改行を挿入すること +with の前後に改行を挿入すること\ また、インデントは下記のように記述すること 良い例: @@ -289,7 +289,7 @@ offset 5 ### HINT 句 -HINT 句は独立した行で記載すること +HINT 句は独立した行で記載すること\ HINT 内容にはインデントを付けること 良い例: @@ -310,8 +310,8 @@ where - 修正コメント - (修正コメントが必要な場合、) - 処理追加の際、追加行の 1 行目の前と最終行の次の行にコメントを入れる。単一行の場合は、同一行の最後にコメントをつける。 + (修正コメントが必要な場合、)\ + 処理追加の際、追加行の 1 行目の前と最終行の次の行にコメントを入れる。単一行の場合は、同一行の最後にコメントをつける。 良い例: @@ -327,8 +327,8 @@ where - 複数行コメント - 「 `/*` `*/` 」を使用する。下記に例を示す。 - なお、前述で触れたとおり、SQL ファイルの先頭にコメントを記述することは禁止とする。 + 「 `/*` `*/` 」を使用する。下記に例を示す。\ + なお、前述で触れたとおり、SQL ファイルの先頭にコメントを記述することは禁止とする。 良い例: @@ -345,15 +345,15 @@ where - 複数行コメントアウト - 複数行をコメントアウトする場合は、各行を「`--`」でコメントアウトする。 - 「 `/*` `*/` 」を使用すると、その中に「 `/*` `*/` 」が存在した場合、コメントアウトが途中で切れてしまう恐れがあるため、 - 使用しない。 + 複数行をコメントアウトする場合は、各行を「`--`」でコメントアウトする。\ + 「 `/*` `*/` 」を使用すると、その中に「 `/*` `*/` 」が存在した場合、コメントアウトが途中で切れてしまう恐れがあるため、\ + 使用しない。 - 論理名の記載 - `select`・`insert`・`update`・`merge`のカラム名記述箇所には単数行コメントでカラムの論理名を記載する。 - `select`・`insert`・`update`・`delete`・`merge`のテーブル名記述箇所には単数行コメントでテーブルの論理名を記載する。 - 論理名は ERD 等で定義された論理名と必ず一致させること。 + `select`・`insert`・`update`・`merge`のカラム名記述箇所には単数行コメントでカラムの論理名を記載する。\ + `select`・`insert`・`update`・`delete`・`merge`のテーブル名記述箇所には単数行コメントでテーブルの論理名を記載する。\ + 論理名は ERD 等で定義された論理名と必ず一致させること。 ## 型変換 @@ -375,8 +375,8 @@ where ## EXISTS 句 -EXISTS 句を記載する際、サブクエリになる SELECT 句の指定は定数「`1`」とする。 -「`*`」(ワイルドカード)や「`'X'`」は統一の観点から利用しない。 +EXISTS 句を記載する際、サブクエリになる SELECT 句の指定は定数「`1`」とする。\ +「`*`」(ワイルドカード)や「`'X'`」は統一の観点から利用しない。\ また「`*`」(ワイルドカード)についてはパフォーマンスの観点からも禁止とする。 良い例: @@ -395,14 +395,14 @@ where ## AS 句 -トップレベルの SELECT 句には必ず`as`句を記載し別名を付ける。 -同一の名前であっても AS 句を付与する。 +トップレベルの SELECT 句には必ず`as`句を記載し別名を付ける。\ +同一の名前であっても AS 句を付与する。\ また、「`as`」は省略可能であるが、省略はしないこと。 ## WHERE 句 -- 論理名の記載 - WHERE 句でカラムと式を比較する際は左辺がカラムになるように記載すること。 +- 論理名の記載\ + WHERE 句でカラムと式を比較する際は左辺がカラムになるように記載すること。 良い例: @@ -412,9 +412,9 @@ where and tbl.amount2 > tbl.amount3 + tbl.amount4 ``` -- 条件式の順序 - 原則として、WHERE 句で条件式を列挙する際、下記の順序を守ること。 - 1. テーブル単位にまとめて順番に記述する +- 条件式の順序\ + 原則として、WHERE 句で条件式を列挙する際、下記の順序を守ること。 + 1. テーブル単位にまとめて順番に記述する\ この際、テーブルの順序は FROM 句に記述した順序に準ずること。 2. 1.のテーブル単位の中で絞り込み条件をまず記述し、その後結合条件を記述する。 @@ -445,19 +445,19 @@ where ## COUNT 文 -レコード数を数える COUNT 文の記述は`count(*)`と記述する。 +レコード数を数える COUNT 文の記述は`count(*)`と記述する。\ `count(1)`・`count('x')` ・`count(key1)`という記載は NG。 ## 文字列リテラル ### エスケープシーケンス -文字列リテラル中のシングルクォーテーションのエスケープは「 `''` 」とシングルクォーテーションを二つつなげた記述をする。 -「 `\'` 」も同様の結果が得られるが円マーク(バックスラッシュ)によるエスケープは利用しない。 -円マークをエスケープせざるを得ないときのみ円マークによるエスケープ利用して良いが、 +文字列リテラル中のシングルクォーテーションのエスケープは「 `''` 」とシングルクォーテーションを二つつなげた記述をする。\ +「 `\'` 」も同様の結果が得られるが円マーク(バックスラッシュ)によるエスケープは利用しない。\ +円マークをエスケープせざるを得ないときのみ円マークによるエスケープ利用して良いが、\ 円マークを文字列リテラルで表現する必要のある設計自体を避けること。 -※PostgreSQL は設定によって円マーク(バックスラッシュ)によるエスケープを無効にできます。(デフォルト無効) +※PostgreSQL は設定によって円マーク(バックスラッシュ)によるエスケープを無効にできます。(デフォルト無効)\ 円マークをエスケープするときは、自プロジェクトでどちらに設定されているか確認してください。 良い例: @@ -489,8 +489,8 @@ set - 中間一致、後方一致検索はインデックスを利用できないため避ける - 検索条件で`=`(等号)を使用できる場合は必ず使用する - `a=1 or a=2`とする方が`a>0 and a<3`などと記述するのよりパフォーマンス上優位な場合が多い。 - これは `a` にインデックスがある場合、`=`であれば、インデックスが有効に使われるためである。 + `a=1 or a=2`とする方が`a>0 and a<3`などと記述するのよりパフォーマンス上優位な場合が多い。\ + これは `a` にインデックスがある場合、`=`であれば、インデックスが有効に使われるためである。 - 可能な限り検索条件にパーティションキーの値を指定する - 全列ワイルドカード「`*`」の使用はせず、カラム名を明記する @@ -546,8 +546,8 @@ set 更新処理におけるコーディング規約を下記に示す。 -- 主キーの値の UPDATE は原則行わない。外部キーがあればエラーになる。 - 外部キーが無い場合でも、事実上、主キーの値を利用して、検索、更新する場合は、リンクが切れてしまう。 +- 主キーの値の UPDATE は原則行わない。外部キーがあればエラーになる。\ + 外部キーが無い場合でも、事実上、主キーの値を利用して、検索、更新する場合は、リンクが切れてしまう。 - パーティションキーの UPDATE は原則行わない。 - VIEW を使用するデータ更新は禁止。更新は実表に対して行う。 @@ -559,7 +559,7 @@ set ## DISTINCT 句 -DISTINCT は、暗黙のソート処理が行われる可能性があるため性能劣化につながる。 +DISTINCT は、暗黙のソート処理が行われる可能性があるため性能劣化につながる。\ EXISTS 句の使用・代替を検討すること。 悪い例: @@ -597,13 +597,13 @@ where ## IN 句 -IN 句は最大 1000 個まで指定できるが、200 個程度でも ORA エラーが発生するケースがある。 -また IN 句の少しだけ異なる SQL が大量に発行されると CPU 高騰やメモリ枯渇を招く。 +IN 句は最大 1000 個まで指定できるが、200 個程度でも ORA エラーが発生するケースがある。\ +また IN 句の少しだけ異なる SQL が大量に発行されると CPU 高騰やメモリ枯渇を招く。\ 従って 100 を超えるような長い IN 句は使用せず、一時表を利用して `in (select ・・・ from 一時表)`のように書き換える。 ## NOT IN 句 -原則`not in(select~)`は使用せずに、`not exists (select~)`を使用する。 +原則`not in(select~)`は使用せずに、`not exists (select~)`を使用する。\ `NOT IN`句は、内部的にソートマージの結合をすることでテーブルをフルスキャンする場合があるため、性能が悪化する可能性がある。 ## UNION 句 diff --git a/eslint.config.mjs b/eslint.config.mjs index 01a6b73e..4f29e489 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -40,13 +40,18 @@ export default defineConfig([ files: ["**/*.md", "*.md"], extends: [ markdown.configs.recommended, - markdownPreferences.configs.recommended, + markdownPreferences.configs.standard, markdownLinks.configs.recommended, ], + language: "markdown-preferences/extended-syntax", rules: { "markdown/no-multiple-h1": "off", - // TODO 修正が大きいので一旦無効化 - "markdown-preferences/hard-linebreak-style": "off", + // Pandoc で変換したときに`:::`がそのまま出力されてしまうので、ちょっとでも不自然に見えないようにpaddingを入れる。 + // (入れない場合 `:::`の後に文章が続いてしまうので流石に違和感がある。) + "markdown-preferences/padded-custom-containers": [ + "error", + { padding: "always" }, + ], "markdown-links/no-dead-urls": [ "error", { diff --git a/package-lock.json b/package-lock.json index 3fe4837a..20954027 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,12 +17,12 @@ "eslint-config-prettier": "^10.0.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-markdown-links": "^0.5.0", - "eslint-plugin-markdown-preferences": "^0.23.0", + "eslint-plugin-markdown-preferences": "^0.32.0", "eslint-plugin-vue": "^10.0.0", "markdown-it-footnote": "^4.0.0", "markdown-it-task-lists": "^2.1.1", "npm-run-all2": "^8.0.0", - "prettier": "^3.4.2", + "prettier": "^3.6.2", "vitepress": "^1.5.0", "vitepress-plugin-mermaid": "^2.0.17", "vue-github-button": "^3.1.3" @@ -2155,6 +2155,13 @@ "license": "MIT", "peer": true }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -2197,15 +2204,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -4397,13 +4395,23 @@ } }, "node_modules/eslint-plugin-markdown-preferences": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-markdown-preferences/-/eslint-plugin-markdown-preferences-0.23.0.tgz", - "integrity": "sha512-GvzEr47d229Vr1Bx8IB0cq11UMAnu3KBxMdsuchyCnF7C0w2mf5mctJNqFVH1aZp1odk7/FsPUQHXeicFeU7ZA==", + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown-preferences/-/eslint-plugin-markdown-preferences-0.32.0.tgz", + "integrity": "sha512-eK6xKRxwDOV7TV+/TwVuacj9C/Jni/FroGlnaohs95r+Wt9PBH4VSVfJBP6JYjm7QPMQlHsNmMmIXxAnZg30Wg==", "dev": true, "license": "MIT", "dependencies": { "emoji-regex-xs": "^2.0.1", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.1.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0", + "micromark-extension-math": "^3.1.0", + "micromark-factory-space": "^2.0.1", + "micromark-util-character": "^2.1.1", + "micromark-util-symbol": "^2.0.1", "string-width": "^8.0.0" }, "engines": { @@ -5762,7 +5770,6 @@ "https://github.com/sponsors/katex" ], "license": "MIT", - "peer": true, "dependencies": { "commander": "^8.3.0" }, @@ -5776,7 +5783,6 @@ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 12" } @@ -6202,6 +6208,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", @@ -6537,6 +6563,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -7540,9 +7586,9 @@ } }, "node_modules/prettier": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.0.tgz", - "integrity": "sha512-ujSB9uXHJKzM/2GBuE0hBOUgC77CN3Bnpqa+g80bkv3T3A93wL/xlzDATHhnhkzifz/UE2SNOvmbTz5hSkDlHw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", "bin": { @@ -8581,6 +8627,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", diff --git a/package.json b/package.json index 239530e4..158d1a3a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "npm run lint:format && npm run lint:js", "lint:js": "eslint . .vitepress", "lint:format": "prettier . --list-different", + "format:eslint": "eslint . .vitepress --fix", "format": "prettier . --write" }, "repository": { @@ -33,12 +34,12 @@ "eslint-config-prettier": "^10.0.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-markdown-links": "^0.5.0", - "eslint-plugin-markdown-preferences": "^0.23.0", + "eslint-plugin-markdown-preferences": "^0.32.0", "eslint-plugin-vue": "^10.0.0", "markdown-it-footnote": "^4.0.0", "markdown-it-task-lists": "^2.1.1", "npm-run-all2": "^8.0.0", - "prettier": "^3.4.2", + "prettier": "^3.6.2", "vitepress": "^1.5.0", "vitepress-plugin-mermaid": "^2.0.17", "vue-github-button": "^3.1.3"