Javaのコメントとは、人間専用のメモを書くための機能です。コンパイル時に無視され、実行には影響を与えません。
Javaだけでなく多くのプログラミング言語に備わっており、適切に使用することでコードの読みやすさを上げられます。
コメントの種類
Javaには、大きく分けて3種類のコメントがあります。
よく使うのは①と②で、③は主にAPI開発者が使うものです。個人開発での出番は少ないでしょう。
では、これらのコメントについて解説していきます。
単一行コメント
// を記述すると、その直後から行末までがコメントとして扱われます。
public class Main {
public static void main(String[] args) {
String name = "佐々木"; // 学生の名前
double gpa = 3.4; // 学生のGPA
// 学生のGPAを表示
System.out.printf("%sさんのGPAは%.1fです%n", name, gpa);
}
}
// とコメント本文の間には半角スペースを設け、行末に書く場合は前にも半角スペースを設けるのが一般的です。行頭に書く場合は、前後の行のインデントに位置を合わせることで見やすくなります。
また、単一行なので、短く、簡潔に書くのが一般的です。長くなりそうな場合は、次に紹介する複数行コメントを使います。
以下によくない例を挙げておきます。動きはしますが、推奨されません。
public class Main {
public static void main(String[] args) {
String name = "佐々木";//半角スペースがない
double gpa = 3.4; // 過剰なスペース
// インデントが揃っていない
System.out.printf("%sさんのGPAは%.1fです%n", name, gpa);
// 長すぎるコメント。エディタによっては折り返して表示されることもあるが、可読性を著しく下げる原因になるため避けるべき
}
}
使いどころ
- 簡単な変数や文の説明
- 複数行にするまでもないコメント
- TODOやFIXME(付箋的な使い方)
複数行コメント
/* */ で囲うと、その内側がすべてコメントとして扱われます。そのため、コメント内で自由に改行できます。
ブロックコメントとも呼ばれます。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
/*
各科目の点数の平均点からの差分を求める
subjectScore: ある学生の科目ごとの点数
subjectAverage: 科目ごとの平均点
pointDiff: 平均点からの差分
*/
int[] subjectScore = {60, 78, 97, 77, 44};
int[] subjectAverage = {70, 70, 65, 60, 80};
int[] pointDiff = new int[5];
/*
forループを回して差分を計算する
*/
for (int i = 0; i < subjectScore.length; i++) {
pointDiff[i] = subjectScore[i] - subjectAverage[i];
}
/* 結果を表示する */
System.out.println(Arrays.toString(pointDiff));
}
}
/* がコメントの開始、 */ がコメントの終了を表します。/* */ の前後には改行を挟むのが一般的です。こちらも、インデントを合わせることで見やすくなります。
なお、「複数行」とは言いますが、23行目のように改行を含めないで使うこともできます。ただし、こういった場合は // を使う方がよいでしょう。
よくない例も挙げておきます。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
/* はじめに改行していない
インデントがそろっていない
*/
int[] subjectScore = {60, 78, 97, 77, 44};
int[] subjectAverage = {70, 70, 65, 60, 80};
int[] pointDiff = new int[5]; /* 行末から複数行コメント
を始めている
*/
for (int i = 0; i < subjectScore.length; i++) {
pointDiff[i] = subjectScore[i] - subjectAverage[i];
}
/*半角スペースがない*/
System.out.println(Arrays.toString(pointDiff));
}
}
使いどころ
- 処理のまとまりやコードブロックの説明
- 一行では長くなりそうなコメント(コメントの内容を削ることも検討する)
- 内部的な挙動・アルゴリズムの解説など、重たい説明
【参考】複数行コメントのさまざまなスタイル
複数行コメントにはさまざまなスタイルがあります。その一部を紹介します。
/*
通常のコメントスタイル
もっとも一般的で、もっとも多くの場面で使われている
エディタの補完もこれに従っていることが多い
*/
/*
* 半角スペースと * を活用して可読性を向上させたスタイル
* 縦軸が揃うので見やすい
* こちらも多くの場面で使われている
*/
/* ==========================================================
* = を活用して強調したスタイル
* 見かける場面は少ないが、稀に使われている
* = ではなく - や # を使うこともある
* ========================================================== */
どんなスタイルを使うかはプロジェクトや組織によって異なるので、ローカルルールがある場合はそれに従うとよいでしょう。
Javadocコメント
/** */ で囲うと、その内側がすべてJavadocコメントとして扱われます。ドキュメンテーションコメントとも呼ばれます。
このコメントは少し特殊で、Javadocで使用します。
Javadocとは
JavaのAPIリファレンスを作成するためのツール、またはAPIリファレンスそのもののことです。
例えば、Javaの公式APIリファレンスもJavadocで作られており、各文章はソースコード内のJavadocコメントによって定義されています。
明確に使用用途が決められており、主にクラス・メンバ・コンストラクタの説明に使います。とりあえず例を見てみましょう。
/**
* Heroクラス<br>
* このクラスは、1人のヒーローを表します。
*/
public class Hero {
/** 体力 */
private int hp;
/** マジックポイント */
private int mp;
/** 攻撃力 */
private int attack;
/**
* 指定された体力、マジックポイント、攻撃力を使って、新たなHeroを構築します。
*/
public Hero(int hp, int mp, int attack) {
this.hp = hp;
this.mp = mp;
this.attack = attack;
}
/**
* 新たなHeroを構築します。
*/
public Hero() {
this(100, 50, 10);
}
/**
* 攻撃するメソッド
* このメソッドを呼び出すと、{@code Monster} の体力が攻撃力の分だけ減少します。
* @param monster 攻撃対象の {@code Monster}
* @return 攻撃後の {@code Monster} の体力
*/
public int attack(Monster monster) {
monster.hp -= attack;
return monster.hp;
}
}
/** がコメントの開始、 */ がコメントの終了を表します。こちらも、/* */ の前後には改行を挟み、インデントを合わせるのが一般的です。
@...
はJavadocタグと呼ばれ、特定の情報を埋め込むのに利用します。@param...
は引数、@return...
は戻り値の説明を表します。
このソースファイルが存在するカレントディレクトリで
$ javadoc -private Hero.java
を実行すると、以下のような index.html ファイルが生成されます。

これはまさにAPIリファレンスです。
このように、JavadocコメントはAPIリファレンス、つまり仕様書を作るのに非常に役立ちます。プログラム内でしか参照できない単一・複数行コメントと違い、HTML形式で視覚的に分かりやすく出力できるのが強みです。
個人開発で使う場面は少ないかもしれませんが、チーム開発では頻繁に登場します。覚えておいて損はないでしょう。
Javadocコメント・Javadocについてもっと詳しく知りたい方は、以下の記事が役立ちます。

コメントアウト
コメントアウトとは、「今は実行させたくないが、とりあえず残しておきたいコード」があるときに、それらをコメントにすることで無効化するテクニックです。
例えば、以下のようなプログラムがあるとします。
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
System.out.println("Hello, Java!");
}
}
このコードでは、Hello, World!
と Hello, Java!
の両方が表示されます。
しかし、(Hello World!
は今は表示させたくない。でも今後差し替えるかもしれないし…)と考えている場合、次のように削除してしまうのはリスクがあります。
public class Main {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
削除すると、将来的に「あれ?ここってこのままでいいんだけ?まぁいっか」となる可能性があります。
そこで、コメントアウトの出番です。
コメントアウトを使うと、次のように書くことができます。
public class Main {
public static void main(String[] args) {
// System.out.println("Hello, World!");
System.out.println("Hello, Java!");
}
}
System.out.println("Hello, World!");
を削除せずコメントにすることで、「差し替え候補」であることを明確に示すことができます。
コメントアウトは以下のような場面で役立ちます:
- コードのデバック中で、一部の処理を止めたいとき
- 将来使う可能性のあるコードを残しておきたいとき
上手に活用すれば、プログラミングがぐっとしやすくなります。ただし、濫用すると可読性が下がるので、本当に必要な場面のみで使うようにしましょう。
先ほどの例も、// Hello World!に差し替える可能性あり
というコメントを代わりに残しておけば、コメントアウトは必要ありません。
コメントアウトの落とし穴
コメントアウトを活用していると、やっかいな落とし穴に出くわすことがあります。
例えば、次のコードの9~19行目をコメントアウトしたいとします。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] intArr = new int[5];
/*
* int型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("数値を入力してください> ");
intArr[i] = sc.nextInt();
} System.out.println();
System.out.println(Arrays.toString(intArr));
String[] strArr = new String[5];
/*
* String型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("文字を入力してください> ");
strArr[i] = sc.next();
} System.out.println();
System.out.println(Arrays.toString(strArr));
}
}
複数行コメントを使えばよさそうです。8行目に /* を、20行目に */ を書きます。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
/*
int[] intArr = new int[5];
/*
* int型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("数値を入力してください> ");
intArr[i] = sc.nextInt();
} System.out.println();
System.out.println(Arrays.toString(intArr));
*/
String[] strArr = new String[5];
/*
* String型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("文字を入力してください> ");
strArr[i] = sc.next();
} System.out.println();
System.out.println(Arrays.toString(strArr));
}
}
ところが、このコードはエラーになります。なぜでしょうか?
8~20行目をよく見てみてください。
/*
int[] intArr = new int[5];
/*
* int型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("数値を入力してください> ");
intArr[i] = sc.nextInt();
} System.out.println();
System.out.println(Arrays.toString(intArr));
*/
8行目が外側のコメント、10行目が内側のコメントの開始部分です。
しかし、10行目にある、内側のコメントの /* は外側のコメントに囲まれているため、単に外側のコメントの一要素として扱われ、「コメントの開始を表す構文」ではなくなっています。
そして、13行目は本来、内側のコメントの終了部分です。ここで問題が発生します。
10行目の /* はコメントの開始部分としての意味を持ちません。つまり、13行目の */ は、外側のコメントの終了部分として扱われてしまいます。
これにより14行目以降はコメントではなく通常のコードとして扱われ、エラーが発生します。

/* … /* … */ … */ のように、複数行コメントの中にさらに複数行コメントを含む構造はネストコメントと呼ばれますが、Javaでは許可されていません。
そのため、コメントアウトしたい範囲に /* */ が存在する場合は、 /* */ ではなく // (単一行コメント)を使う必要があります。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// int[] intArr = new int[5];
// /*
// * int型で入力を5回受け付ける
// * その後、配列に格納する
// */
// for (int i = 0; i < 5; i++) {
// System.out.print("数値を入力してください> ");
// intArr[i] = sc.nextInt();
// } System.out.println();
//
// System.out.println(Arrays.toString(intArr));
String[] strArr = new String[5];
/*
* String型で入力を5回受け付ける
* その後、配列に格納する
*/
for (int i = 0; i < 5; i++) {
System.out.print("文字を入力してください> ");
strArr[i] = sc.next();
} System.out.println();
System.out.println(Arrays.toString(strArr));
}
}
こうすることで、問題なくコメントアウトできます。上級者でもうっかり見落としやすい落とし穴なので、十分に注意しましょう。
日頃から意識したい点
長すぎるコメントは避ける
単一行コメントの項で少し説明しましたが、たとえ複数行・Javadocコメントであっても、長すぎるコメントは避けるべきです。
例えば、次のようなコメントがあったら、どうでしょうか?
/*
* ここでは、Heroクラスのattackメソッドを呼び出す操作を実行しています。
* このattackメソッドは、Heroクラスのインスタンスに定義されている
* インスタンスメソッドであり、その目的は引数として与えられたMonster型の
* オブジェクトに対して攻撃処理を実行することにあります。
*
* 攻撃処理の具体的な中身についてはHeroクラスの実装によって異なりますが、
* 一般的にはMonsterのHPを減少させたり、攻撃の成功 / 失敗に応じた
* ロジックが内部的に実行されるものと推測されます。
*
* また、ここで与えるMonsterオブジェクトはすでに事前に
* インスタンス化されている必要があり、attackメソッドの引数として
* 正しく渡せる状態でなければなりません。
*
* したがって、以下の1行で記述されている attackメソッドの呼び出しは、
* Heroインスタンスが有効な状態で生成されており、
* かつMonsterインスタンスが適切に初期化された状態で存在しているという
* 前提のもとに実行されることになります。
*
* 読者の混乱を避けるため、attackメソッドの戻り値型や例外処理などについては
* 今回の説明からは意図的に除外しています。
*/
hero.attack(monster);
コードは hero.attack(monster);
だけなのに、それに対するコメントが明らかに過剰です。このようなコメントは可読性を下げるだけでなく、読む人に徒労感を与える原因にもなりかねません。
「自分しか見ない」とか「学習のメモとして使っている」とかなら長くても構いませんが、そうでない場合、長くても10行以内、できれば3~5行程度にまとめるようにしましょう。
コードから分かることはコメントにしない
「複数行コメント」項で登場したコードをもう一度見てみましょう。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
/*
各科目の点数の平均点からの差分を求める
subjectScore: ある学生の科目ごとの点数
subjectAverage: 科目ごとの平均点
pointDiff: 平均点からの差分
*/
int[] subjectScore = {60, 78, 97, 77, 44};
int[] subjectAverage = {70, 70, 65, 60, 80};
int[] pointDiff = new int[5];
/*
forループを回して差分を計算する
*/
for (int i = 0; i < subjectScore.length; i++) {
pointDiff[i] = subjectScore[i] - subjectAverage[i];
}
/* 結果を表示する */
System.out.println(Arrays.toString(pointDiff));
}
}
このコードのコメントには良くない点がいくつかありますが、その1つが「コードから分かることをわざわざコメントにしている」ということです。
例えば、23行目の /* 結果を表示する */
は、System.out.println(...);
を見れば明らかに分かります。そのため、コメントは冗長なだけになってしまっています。
このようなコメントは削除するか、文言を変えるなどするとスッキリします。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] subjectScore = {60, 78, 97, 77, 44}; // ある学生の点数
int[] subjectAverage = {70, 70, 65, 60, 80};
int[] pointDiff = new int[5];
// 各科目の平均点からの差分を求める
for (int i = 0; i < subjectScore.length; i++) {
pointDiff[i] = subjectScore[i] - subjectAverage[i];
}
System.out.println(Arrays.toString(pointDiff));
}
}
なお、「コードから分かることはコメントにしない」というのは、裏を返せば「コメントが無くても分かるコードを書く」ということにつながります。
以下の2つの例を比較してみましょう。
public class Main {
public static void main(String[] args) {
// 学生の名前を格納する変数
String aaa;
// 学生の名前を代入
aaa = "水野";
}
}
public class Main {
public static void main(String[] args) {
String studentName;
studentName = "水野";
}
}
後者はコメントなしでも何をしているかが明確で、コードが簡潔かつ読みやすくなっています。
このように、「読むだけで意図が分かるコード」のことを、自己記述的なコードと言います。なるべく自己記述的になるように心がけ、コメントは最小限にとどめるようにしましょう。
コメントの”粒度”を意識する
「コードから分かることはコメントにしない」項とも被りますが、あまりに細かすぎる・頻繁すぎるコメントは避けるべきです。
以下の2つの例では、どちらがより良いでしょうか?
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("入力する数値の個数> ");
int n = sc.nextInt(); // 数値の個数を格納
int[] inputs = new int[n]; // 入力を格納する配列
for (int i = 0; i < n; i++) { // n回分の入力
int e = sc.nextInt(); // 入力を読み取る
inputs[i] = e;
}
System.out.println("結果:" + Arrays.toString(inputs));
}
}
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 指定された回数分だけ入力(整数)を読み取り、配列に格納する
System.out.print("入力する数値の個数> ");
int n = sc.nextInt();
int[] inputs = new int[n];
for (int i = 0; i < n; i++) {
int e = sc.nextInt();
inputs[i] = e;
}
System.out.println("結果:" + Arrays.toString(inputs));
}
}
前者は一見丁寧ですが、一行一行を順に追わないと何をしているのか分かりづらいコメントになっています。これでは、読むのも疲れてしまいます。
一方、後者はコメントを1つにまとめたことで、コメントの数も少なく抑えられ、何をしているのかも分かりやすくなっています。
このように、コメントを「意味のまとまり」単位で書くことで、コメントの数を減らしつつ、意図を明確に示すことができます。はじめは「意味のまとまり」をつかむのは難しいかもしれませんが、積極的に意識しましょう。
これまでに紹介した3点をつねに意識するのは難しいかもしれません。そんな時は「コードはHOW、コメントはWHY」と考えるとよいです。
以下のコードを見てください。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] scores = {80, 90, 70, 60, 75};
// 同点はあり得ないため高速なクイックソートを使用
// Arrays.sort()を使わないことで、アルゴリズムを可視化(取引先からの要望)
quickSort(scores);
System.out.println(Arrays.toString(scores));
}
// クイックソートの実装メソッド群
public static void quickSort(int[] array) {
quickSort(array, 0, array.length - 1);
}
private static void quickSort(int[] array, int low, int high) {
if (low < high) {
int pivotIndex = partition(array, low, high);
quickSort(array, low, pivotIndex - 1); // ピボットの左側
quickSort(array, pivotIndex + 1, high); // ピボットの右側
}
}
private static int partition(int[] array, int low, int high) {
int pivot = array[high]; // 最後の要素をピボットとする
int i = low - 1; // 小さい値の境界を記録
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
swap(array, i, j);
}
}
swap(array, i + 1, high); // ピボットを正しい位置に移動
return i + 1; // ピボットのインデックスを返す
}
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
少々長いですが、このコードはクイックソートを使って、配列 scores
を昇順にソートするものです。main
メソッド内で quickSort
メソッドを呼び出して、ソートを行っています。
しかし、見ていただきたいのは15~48行目の実装部分ではなく、8~10行目のコメントとコードです。
この部分において、コメントは「なぜ(WHY)クイックソートを明示的に使うのか」を、コードは「どのように(HOW)クイックソートを実装しているのか」を表しています。
なぜこの実装なのか、なぜこのアルゴリズムなのか、なぜこの命名なのか…などは、コードを読むだけでは分かりません。それを補うことこそ、コメントの仕事というわけです。
つまり、以下のようにまとめられます:
- コメントはプログラマの意図を示すもの。WHYを意識する
- コードは処理(実装)の流れを示すもの。HOWを意識する
これを意識するだけでコメントとコードの質が跳ね上がるので、頭の片隅に入れておくとよいでしょう。
「よいコメント」についてもっと詳しく知りたい方は、以下の記事が役立ちます。
まとめ
今回はJavaのコメントについて解説しました。文法的にはとても単純ですが、掘り下げると意外と奥深いです。
コメントは正しく使えば非常に強力なツールです。正しい使い方を覚えて、自身のコードをよりよいものにしましょう!
コメント