2011-06-14 2 views
4

어리석은 문제의 종류 나는 여기에 직면 해있다. 기본적으로 For 루프에 있고이 루프 내에서 버튼을 만드는 함수를 호출하고있다. 그러나이 함수에서는 버튼을 구분하기 위해 루프 반복기를 전달하려고합니다. 그러나 그것은 루프 반복자 "final"을 만들어야한다는 것을 의미합니다.자바 - 루프 내부의 함수에 루프 반복자를 가져 오는 중입니까?

잘 내 문제는 일부 골격 코드를 더 이해를 만들 것입니다 : 내가 아는

for(int i = 0; i < appList.size(); i++) { 

       //some other stuff including creating the below button 'btn' 

       btn.setOnClickListener(new View.OnClickListener() { 
        public void onClick(View v) { 
         //set some attribute based on i 
         //but when I do this it only sets based on the greatest value of i (!) 
        } 
       }); 
} 

시큰둥 좀 바보 문제는 ... 내가 자바에 새로운 생각 해요!

건배.

+0

* i *의 최대 값을 사용하여 *를 기반으로 속성을 설정한다는 설명은 정확하지 않습니다. 답변에 표시된 키워드 'final'이 없기 때문에 스 니펫이 포함 된 코드를 컴파일 할 수 없어야합니다. 마지막 단일 요소 배열에 정수를 래핑했을 수도 있습니다. 그러면 설명하는 동작을 얻을 수 있습니다. – Atreys

답변

4
for(int i = 0; i < appList.size(); i++) { 

    final int _i = i; 

    btn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      // use _i instead of i 
     } 
    }); 
} 
+1

'_i'은'final'이라고 선언해야합니다 –

+0

그래, 전체적인 점이었습니다 :) –

+0

그래서 나를 이길 정도로 upvote ;-) –

1

바보 예 코드의 비트 고려해 i 변경할 때

int i = 0; 
obj.invokeThunkAfter10Seconds(new ThunkObject() { 
    public void thunk() { 
     System.out.println(i); 
    } 
} 
i = 1; 
ThunkObjecti에 대한 참조를 보유

하지만 i 변경할 수있는 출력을 예측할 수 및에 의존 thunk 호출됩니다.

Java는 적절한 닫힘 (설계 상 Cannot refer to a non-final variable inside an inner class defined in a different method 참조)이 없으므로 이와 같이 최종 변수 (예 : 변경 가능)를 캡처 할 수 없습니다.

대신 변수 final을 선언해야합니다. 즉, 초기화되었으므로 변경할 수 없음을 의미합니다. 즉, 내부 클래스에 의해 캡처 된 후에는 i을 변경할 수 없습니다. 당신의 예에서

final int i = 0; 
obj.invokeThunkAfter10Seconds(new ThunkObject() { 
    public void thunk() { 
     System.out.println(i); 
    } 
} 
// Can't change i here. It will forever now be 0. 

당신은 각 루프 반복의 값을 변경하려면 않기 때문에, 마지막으로 i을 설정할 수 없습니다. 대신 최종 변수에 값의 사본을 만들 수 있습니다.

for(int i = 0; i < appList.size(); i++) { 
    //some other stuff including creating the below button 'btn' 

    final int capturedI = i; 
    btn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      //set some attribute based on capturedI 
     } 
    }); 
}