Javaでコーディングしているとき、スペースの使いどころについて、生成AIにサンプルコードを作ってもらいました。自分のメモとして記事に残しておきます。
- キーワードと ( の間
if、for、catch などのキーワードの直後に ( が続く場合、その間にスペースを1つ入れる。 - } と else / catch などのキーワードの間
閉じ波括弧 } の直後に else や catch などのキーワードが続く場合、その間にスペースを1つ入れる。 - 開き波括弧 { の前
原則として、開き波括弧 { の直前にはスペースを1つ入れる。
例外1:アノテーションの配列引数
次のようなアノテーションでは、{ の前にスペースを入れない。
@SomeAnnotation({a, b})
例外2:配列の二重波括弧
次のような配列初期化では、{{ の間にスペースは不要。
String[][] x = {{"foo"}};
これは後述する 9. 配列初期化子の {} 内のスペースにも関係する。
4. 二項演算子・三項演算子の両側
二項演算子・三項演算子の両側にはスペースを1つ入れる。
5. ,、;、:、キャストの ) の後
以下の記号の直後にはスペースを1つ入れる。
カンマ ,
コロン :
セミコロン ;
キャストの閉じ丸括弧 )
6. // の前
// で始まるコメントの直前には、内容と // の間にスペースを入れる。
7. // とコメント本文の間
// で始まるコメントでは、// とコメント本文の間にスペースを入れる。
8. 型と識別子の間
変数やフィールド、引数などを宣言するとき、型と識別子の間にはスペースを1つ入れる。
9. 配列初期化子 {} の内側
配列初期化子の {} の内側のスペースは任意。
10. 型アノテーションと [] / ... の間
型アノテーションと [] または ... の間にはスペースを入れる。
import java.io.IOException;
import java.util.List;
public class SpacingExample {
// 6, 7: // の前後にはスペース
private static final String MESSAGE = "hello"; // comment
// 10: 型アノテーションと [] / ... の間にはスペース
public void process(
String @TypeUseAnnotation [] values,
String @TypeUseAnnotation ... args) {
// ここからメソッド本体
}
// 3: { の前にスペース
public void example(int value) {
// 1: キーワードと ( の間にスペース
if (value > 0) {
System.out.println("positive");
} else {
// 2: } と else の間にスペース
System.out.println("zero or negative");
}
// 4: 二項演算子の両側にスペース
int result = value + 10;
// 4: 三項演算子の両側にスペース
String text = value > 0 ? "positive" : "negative";
// 4: 拡張for文の : の両側にスペース
List<String> names = List.of("Alice", "Bob");
for (String name : names) {
System.out.println(name);
}
// 4: lambda の -> の両側にスペース
names.forEach((String name) -> System.out.println(name));
// 4: catch の | の両側にスペース
try {
throwException();
} catch (IOException | IllegalStateException e) {
// 1: catch と ( の間にスペース
System.out.println(e.getMessage());
}
// 4: 型境界の & の両側にスペース
GenericExample<String> generic = new GenericExample<>();
// 4: switch rule の -> の両側にスペース
switch (text) {
case "positive" -> System.out.println("positive");
case "negative" -> System.out.println("negative");
default -> System.out.println("unknown");
}
// :: はスペースを入れない
names.stream().map(String::toUpperCase).forEach(System.out::println);
// . はスペースを入れない
System.out.println(names.size());
// 5: , の後にスペース
int[] numbers = new int[] {1, 2, 3};
// 9: 配列初期化子の { } 内のスペースは任意
int[] numbersWithSpaces = new int[] { 1, 2, 3 };
// 9: 二重 { の間にはスペースを要求しない
String[][] matrix = {{"foo"}};
// 3: 配列初期化子以外の { の前にはスペース
if (numbers.length > 0) {
System.out.println(numbers[0]);
}
}
// 5: キャストの ) の後にはスペース
public void castExample(Object value) {
String text = (String) value;
System.out.println(text);
}
// 8: 型と識別子の間にスペース
private int count = 10;
// 4: 複数の演算子の両側にスペース
public int calculate(int a, int b) {
return a * 2 + b / 3;
}
// 4: ジェネリック型境界の &
private <T extends Runnable & AutoCloseable> void execute(T task) {
try {
task.run();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void throwException() throws IOException {
throw new IOException("error");
}
@SomeAnnotation({1, 2, 3})
public void annotatedMethod() {
System.out.println("annotated");
}
// 3 の例外:
// @SomeAnnotation({1, 2, 3}) の { の前にはスペースを入れない
// これは通常の @Annotation の引数内だから
}
class GenericExample<T> {
private final T value;
GenericExample() {
this.value = null;
}
}
@interface SomeAnnotation {
int[] value();
}
@interface TypeUseAnnotation {
}