Рассмотрим этот бит глупого примера кода:
int i = 0;
obj.invokeThunkAfter10Seconds(new ThunkObject() {
public void thunk() {
System.out.println(i);
}
}
i = 1;
ThunkObject
содержит ссылку на i
, но i
может измениться, что делает вывод непредсказуемым и зависит от того, когда i
изменяется, и когда вызывается thunk
.
Поскольку Java не имеет надлежащих замыканий (по проекту см. Невозможно обратиться к неконечной переменной внутри внутреннего класса, определенного в другом методе), вам явно не разрешено захватывать неконечные (то есть изменяемые) переменные, подобные этой.
Вместо этого вы должны объявить переменную 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
}
});
}