このJavaコードは、Runnable
インターフェースの実装としてラムダ式を使用してスレッドを生成し、実行しています。私はこのコードにコメントを加えて、どのように動作するのかを説明し、それがなぜ答えD「コンパイルエラーが発生する」になるのかを解説します。
public class Sample {
public static void main(String[] args) {
int cnt = 0; // メインメソッドのスコープでカウンタ変数cntを宣言して0で初期化
// ラムダ式を使ってRunnableインターフェースの実装を作成
Runnable r = () -> {
// ラムダ式の中でcnt変数を再宣言している。これはスコープが異なるためエラーにはならないが、
// このcntは外側のcnt変数とは異なる変数である。
for (cnt = 0; cnt < 10; cnt++) {
// このcnt++はループの中でカウンタを増やすために使われているが、
// これが実際にはラムダ式の外側のcnt変数を変更しようとしていることになる。
// Javaのラムダ式では、ラムダ式の外側のローカル変数を変更することは許されていない。
// この行はコンパイルエラーを発生させる。
System.out.println(cnt++);
}
};
// 新しいスレッドを作成してラムダ式を実行
new Thread(r).start();
}
}
このコードの問題点は、ラムダ式内で外部のローカル変数cnt
を変更しようとしていることです。Javaでは、ラムダ式から参照される外部のローカル変数は実質的にfinal
である必要があります。つまり、ラムダ式内部で変更することはできません。しかし、ここではfor
ループの中でcnt++
というインクリメント演算を行っているため、コンパイルエラーが発生します。
そのため、答えは「D. コンパイルエラーが発生する」となります。
追記
コンパイルエラーを避けるには、ラムダ式内で外部のローカル変数を変更しないようにする必要があります。このコードでは、Runnable
インターフェースの実装内でループ変数cnt
を使用していますが、これが外部スコープの変数cnt
と衝突しています。コンパイルエラーを避けるためには、ラムダ式内で使用するカウンタ変数を独立させる必要があります。
以下はそのための修正案です:
public class Sample {
public static void main(String[] args) {
// ラムダ式から参照されるローカル変数はfinalまたは実質的finalである必要があるため、
// ラムダ式内で変更する変数はラムダ式内で宣言する。
Runnable r = () -> {
for (int i = 0; i < 10; i++) {
// ラムダ式内で独立したループカウンタiを使用。
System.out.println(i);
}
};
// Runnableの実装をThreadコンストラクタに渡してスレッドを起動
new Thread(r).start();
}
}
この変更により、Runnable
の実装内で新しいカウンタ変数i
を導入しました。この変数はRunnable
の実装内でのみスコープされるため、外部の変数に干渉せず、コンパイルエラーが発生しません。また、Runnable
実装外で宣言されたcnt
変数はもはや不要なので、削除することができます。
Top comments (0)