aymnkt
@aymnkt

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

拡張for文の処理流れ、及び一時変数がfinalである場合の考え方

Q&A

Closed

解決したいこと

拡張for文において、今までの自分の理解では配列が順番に一時変数に代入されていくという感じで、下記のように

int[] ary = {10, 20, 30};
for(final int tmp : ary){
   System.out.println(tmp);
   }

と記述し、一時変数を定数とした場合、コンパイルエラーになるかと考えましたが、エラーにはなりません。

考えたこと・調べたこと

拡張for文の場合は通常のfor文とは異なり、Iteratorインタフェースが呼ばれて、メソッドの戻り値として値を受け取るのでエラーにはならないということでしょうか。

知りたいこと

より理解を深めたいため、拡張for文の開始から実行されインタフェースやメソッドの呼び出し順序が知りたいです。

0

2Answer

拡張for文の場合は通常のfor文とは異なり、Iteratorインタフェースが呼ばれて、メソッドの戻り値として値を受け取るのでエラーにはならないということでしょうか。

通常のfor文 / 拡張for文は関係なく、final変数を更新しなければコンパイルエラーになりません。

通常のfor文でfinal変数がコンパイルエラーになるのは、n++のように更新するからであって、それをしなければコンパイルエラーにはなりません。

for(final int n=0; n<3; n++) { ・・・ }  //n++ がエラー

for(final int n=0; n<3; ) { ・・・ }  //エラーにならない(ただし、無限ループ?)
1Like

Comments

  1. @aymnkt

    Questioner

    @nak435 さん、ありがとうございます。

  2. もしかして、「Iteratorが更新しているじゃないか」と思われるかもしれませんが、
    「Iteratorが更新した値を定数化する」ということで、元々のコードで言うところの、tmp変数を更新しない限り、finalでエラーになることは無い、と言う理解です。

  3. @aymnkt

    Questioner

    @nak435 さん、Iteratorが更新してるじゃないかと思っていました!スッキリしました。ありがとうございます。

  4. 解決したようでしたら、質問をクローズにするといいですよ。

  5. @aymnkt

    Questioner

    @jinbei230525 さん、すみませんありがとうございます。抜けてました。

拡張for文は、イテレータを使用して配列やコレクションを簡潔に処理するための構文糖衣です。具体的には、拡張for文は内部でIteratorを生成し、そのIteratorを使用して要素に順次アクセスします。

以下は、拡張for文の基本的な動作フローです。

  1. 拡張for文が開始されると、対象の配列やコレクションからIteratorが生成されます。
  2. Iteratorが持つhasNext()メソッドが呼ばれ、次の要素があるかどうかを確認します。
  3. もしhasNext()trueを返した場合、次にnext()メソッドが呼ばれて次の要素が取得されます。
  4. 次に、拡張for文の変数に取得した要素が代入され、ブロック内の処理が実行されます。
  5. これを繰り返して、全ての要素が処理されるまで続きます。

拡張for文の内部でIteratorが使用されているため、配列やコレクションがIteratorをサポートしている限り、拡張for文は正しく動作します。そのため、配列の場合でもコンパイルエラーにならないのは、Iteratorが正しく実装されているからです。

今回のコード例であるfor(final int tmp : ary)では、aryはint型の配列であり、int型はプリミティブ型であるため、Iteratorがプリミティブ型をサポートしている場合、Wrapperクラス(Integerなど)に変換されて拡張for文が処理されます。

0Like

Comments

  1. @aymnkt

    Questioner

    @ORCHESTRA_TAPE さん、ありがとうございます。理解が深まりました。

Your answer might help someone💌