2009-10-09 3 views
4

저는 for-each-loop를 가지고 있습니다 :이 코드는 모든 반복에서 평가됩니까?

for (Component c : container.getComponents()) { 
    // Loop code 
} 

getComponents이 모든 반복마다 호출 되었습니까? getComponents을 외형보다 먼저 호출하고 캐시 된 배열에서만 작동하는 것이 합리적입니까?

답변

17

아니요, getComponents()는 한 번만 호출됩니다.

for (Iterator<Component> iterator = container.getComponents().getIterator(); 
    iterator.hasNext();) 
{ 
    Component c = iterator.next(); 
    ... 
} 

section 14.14.2 of the Java Language Specification에서 :

그것은 동등한의

성명의 형태가 강화 :

EnhancedForStatement :

for (VariableModifiersopt Type Identifier: Expression) Statement 

표현식은 Iterable 유형이어야하며, 그렇지 않으면 배열 유형 (§10.1)이어야하며> 그렇지 않으면 컴파일 타임 오류가 발생합니다. 문 (§14.14)에 향상된의 FormalParameter 부에서 선언 된 로컬 변수의 범위는 포함 된 정책

문 향상된가 기본 for 문장으로 번역 주어진다의 의미이다.

표현식 유형이 Iterable의 하위 유형 인 경우 표현식 Expression.iterator()의 유형으로 지정합니다. 문 향상된 양식의 기본 for 문에 해당합니다 :

for (I #i = Expression.iterator(); #i.hasNext();) { 
    VariableModifiersopt Type Identifier = #i.next(); 
    Statement 
} 
+1

Jon, 컴파일러는 getComponents()가 부작용이없고 각 반복마다 다른 것을 생성하지 않는다는 것을 어떻게 보장합니까? (예 : 다른 스레드가 구성 요소를 변경하면?). – Uri

+1

그것은하지 않습니다 ...하지만 위의 번역은 기본적으로 그것이 정의 된 것입니다. 나는 JLS 레퍼런스를 찾으려고 노력할 것이다. –

+0

제 잘못입니다. 나는 소스 코드를 잘못 읽었다. 나는 OP가 for 루프의 제어 조건이 재평가되는지 여부를 묻고 있다고 생각했다. 나는 이것이 각각을위한 것임을 알지 못했다. – Uri

0

이 (내가를 int로 = 0 ....

그냥 foreach 루프가 없습니다 "긴 손을"그 일을 같은 실제 바이트 코드 변환과 프로그래밍 시간을 절약 ?? 한마디로

는 getComponent는()는

+1

아니요, foreach 루프가 작동하는 방식이 아닙니다. getComponent()는 한 번만 호출되지만 사실은 마찬가지입니다. –

+0

이것은 -1이 될 자격이 없었습니다 (이전의 가정은 잘못되었지만 실제 응답은 정확합니다). 그래서 여기에 +1이 있습니다. –

10

getComponents 한 번 호출됩니다 번만 호출해야하며, 반복자를 반환 이 반복자는 next() 및 hasNext() 메서드를 사용하여 호출됩니다.

업데이트 좀 더 자세히 시도해보십시오. Skeet Jon Skeet이 답변입니다.

다음 프로그램은 컬렉션에 세 개의 항목이 있더라도 iterator에 대한 호출이 한 번 수행되는 방법을 보여줍니다.

public static void main(String[] args) { 
    List<String> list = new ArrayList<String>() { 
     public java.util.Iterator<String> iterator() { 
      System.out.println("iterator() called"); 
      return super.iterator(); 
     }; 
    }; 
    list.add("a"); 
    list.add("b"); 
    list.add("c"); 

    for (String s : list) { 
     System.out.println(s); 
    } 
} 

출력 : 당신은 자바 디 컴파일러를 통해이를 실행하면

iterator() called 
a 
b 
c 

, 당신은 다음과 같은 코드를 확인할 수있는 것들 : 우리가 JLS 14.14.1 알고 있기 때문에,

String s; 
    for(Iterator iterator = list.iterator(); iterator.hasNext(); System.out.println(s)) 
     s = (String)iterator.next(); 

Addtionally을 그 for 문의 첫 번째 섹션은 한 번만 실행되므로 iterator 메소드가 여러 번 호출되지 않는다는 점을 확신 할 수있다.

2

는 getComponents 모든 반복 호출되어 있습니까?

호 자바 foreach 루프는 Iterable 인터페이스에 기초하여,이 코드

유일한 차이점 반복자 숨겨져 있다는 동등하다.

3

Java LanguageSpecification 14.14.2는 말한다 :

EnhancedForStatement :
for (VariableModifiersopt Type Identifier: Expression) Statement

표현의 유형의 Iterable의 서브 타입 인 경우,() 나는 표현 Expression.iterator의 유형하자 . 문이 향상된 형태의 문장을위한 기본 동등하다 : #I 어떤 다른 식별자 (구별되는 컴파일러 생성 식별자

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

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

컴파일러 생성 또는 그렇지 않은 경우) 진술에 대한 향상 지점에서 범위 (§6.3) 에있는.

그래서 표현식은 초기화 과정에서 한 번만 평가됩니다.