Java 강화 for 루프에서 루프될 표현식이 한 번만 평가된다고 가정하는 것이 안전합니까?

StackOverflow https://stackoverflow.com/questions/1618202

문제

Java에서는 for-each 루프입니다.
배열을 생성하는 메서드가 있는 경우 genArray().

다음 코드에서는 호출을 통해 매번 배열이 다시 생성됩니까? genArray()?아니면 Java가 메소드를 한 번 호출하고 배열의 복사본을 저장합니까?

for (String s : genArray())
{
    //...
}

감사해요

도움이 되었습니까?

해결책

에 대한 향상된 for 문, Java 언어 사양은 다음과 같이 기록됩니다.

진술을 위해 향상된 것은 다음에 양식을 가지고 있습니다.

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

표현식에는 다음 중 하나의 유형이 있어야 합니다. Iterable 그렇지 않으면 배열 유형 (§10.1)이거나 컴파일 타임 오류가 발생해야합니다.

Enhanced의 공식 파라미터 부분에 선언 된 로컬 변수의 범위 for 문 (§14.14)은 포함 된 진술입니다

강화의 의미 for진술은 기본으로 번역하여 제공됩니다 for 성명.

유형의 경우 Expression 하위 유형입니다 Iterable, 그럼 하자 I 표현의 유형이 되십시오 표현.iterator().향상된 for 진술은 기본과 동일합니다 for 양식의 진술 :

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}

어디 #i 진술이 발생하는 시점에서 스코프 (§6.3)에있는 다른 식별자 (컴파일러 생성 또는 기타)와 구별되는 컴파일러 생성 식별자입니다.

그렇지 않으면 표현식에는 반드시 배열 유형이 있으며 T[].허락하다 L1 ... Lm향상된 직전에 (아마도 비어있는) 라벨 시퀀스가 ​​되십시오. for 성명.그런 다음 진술에 대한 강화의 의미는 다음 기본에 의해 제공됩니다. for성명:

T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
        VariableModifiersopt Type Identifier = a[i];
        Statement
}

어디 그리고 명령문이 발생하는 시점에서 범위에있는 다른 식별자 (컴파일러 생성 또는 기타)와 구별되는 컴파일러 생성 식별자입니다.

따라서 귀하의 경우에는 genArray() 하위 유형을 반환하지 않습니다 Iterable 하지만 배열 유형이므로 향상된 for 명령문은 다음 기본 내용과 동일합니다. for 성명:

String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
    String s = a[i];
    // ...
}

그리고 genArray() 따라서 한 번만 호출됩니다 (그러나 현재 허용되는 답변은 부분적으로 잘못되었습니다).

다른 팁

Java는 GenArray ()를 한 번 호출하여 반복자 객체를 가져 와서 여러 번 호출합니다.

한 번만 사용해야합니다. 이것을 호출하는 것과 동일합니다.

  String[] strings = genArray();
  for (String s : strings) {
  ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top