8章4

この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(); }
}
Enter fullscreen mode
Exit fullscreen mode

このコードの問題点は、ラムダ式内で外部のローカル変数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(); }
}
Enter fullscreen mode
Exit fullscreen mode

この変更により、Runnableの実装内で新しいカウンタ変数iを導入しました。この変数はRunnableの実装内でのみスコープされるため、外部の変数に干渉せず、コンパイルエラーが発生しません。また、Runnable実装外で宣言されたcnt変数はもはや不要なので、削除することができます。


Discover more from Coursity

Subscribe to get the latest posts sent to your email.

Leave a Comment

Your email address will not be published. Required fields are marked *

Discover more from Coursity

Subscribe now to keep reading and get access to the full archive.

Continue reading

Scroll to Top
Martins ad network.