저는 for-each-loop를 가지고 있습니다 :이 코드는 모든 반복에서 평가됩니까?
for (Component c : container.getComponents()) {
// Loop code
}
getComponents
이 모든 반복마다 호출 되었습니까? getComponents
을 외형보다 먼저 호출하고 캐시 된 배열에서만 작동하는 것이 합리적입니까?
저는 for-each-loop를 가지고 있습니다 :이 코드는 모든 반복에서 평가됩니까?
for (Component c : container.getComponents()) {
// Loop code
}
getComponents
이 모든 반복마다 호출 되었습니까? getComponents
을 외형보다 먼저 호출하고 캐시 된 배열에서만 작동하는 것이 합리적입니까?
아니요, 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 }
이 (내가를 int로 = 0 ....
그냥 foreach 루프가 없습니다 "긴 손을"그 일을 같은 실제 바이트 코드 변환과 프로그래밍 시간을 절약 ?? 한마디로
는 getComponent는()는
아니요, foreach 루프가 작동하는 방식이 아닙니다. getComponent()는 한 번만 호출되지만 사실은 마찬가지입니다. –
이것은 -1이 될 자격이 없었습니다 (이전의 가정은 잘못되었지만 실제 응답은 정확합니다). 그래서 여기에 +1이 있습니다. –
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 메소드가 여러 번 호출되지 않는다는 점을 확신 할 수있다.
는 getComponents 모든 반복 호출되어 있습니까?
호 자바 foreach 루프는 Iterable 인터페이스에 기초하여,이 코드
유일한 차이점 반복자 숨겨져 있다는 동등하다.
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) 에있는.
그래서 표현식은 초기화 과정에서 한 번만 평가됩니다.
Jon, 컴파일러는 getComponents()가 부작용이없고 각 반복마다 다른 것을 생성하지 않는다는 것을 어떻게 보장합니까? (예 : 다른 스레드가 구성 요소를 변경하면?). – Uri
그것은하지 않습니다 ...하지만 위의 번역은 기본적으로 그것이 정의 된 것입니다. 나는 JLS 레퍼런스를 찾으려고 노력할 것이다. –
제 잘못입니다. 나는 소스 코드를 잘못 읽었다. 나는 OP가 for 루프의 제어 조건이 재평가되는지 여부를 묻고 있다고 생각했다. 나는 이것이 각각을위한 것임을 알지 못했다. – Uri