Wielkim "problemem" z wielowątkowością, a także całym powodem jego używania, jest to, że wiele rzeczy dzieje się w tym samym czasie. Nagle wartość dowolnej zmiennej, do której wątek uzyskuje dostęp, która nie jest lokalna dla wątku, może się zmienić w dowolnym momencie. Tak więc, można rzecz, jesteś po prostu drukuje numery 1-10 z tego kodu:
int x = 0; //supposing that this was allowed to be non-final...
private class myRun implements Runnable{
@Override
public void run() {
for (int i=0; i<10; i++) {
System.Out.Println(x++);
}
}
}
Jednak w rzeczywistości, jeśli inny kod w tej klasie zmienia wartość X, może skończyć się drukowanie 230498 - 230508 Wartość x może zmienić zmianę w środku pętli. Jeśli nie możesz polegać na x
posiadającej określoną wartość lub zachowującej wcześniej przypisaną jej wartość, używanie jej w kodzie staje się daremne. Dlaczego używałbyś zmiennej, gdyby jej zawartość mogła się zmienić po kropli kapelusza?
Zamiast tylko zabraniać ci używania go w ogóle, Java wymaga, abyś go zrobił final
. Możesz po prostu "obiecać", aby nigdy nie zmieniać wartości x
z innego wątku, ale dlaczego nie uczynić go w pierwszej kolejności final
i pozwolić kompilatorowi pomóc?Oczywiście, masz dostęp tylko do wartości początkowej przypisanej do x
, ale tylko możliwość uzyskania dostępu do wartości początkowej zmiennej jest lepsza niż niemożność jej użycia w ogóle, co skutecznie odcięłoby zdolność wątku do wykorzystania danych z reszty twojej klasy.
Ponieważ tak definiuje się język. Prawdopodobnie, aby zmienne * zmiennych * nie były modyfikowane we wspomnianej metodzie w * anonimowej klasie wewnętrznej *. (Sądzę, że to również upraszcza implementację: tylko wartości * muszą być skopiowane z użyciem proxy do anonimowego typu, a oryginalne zmienne nie muszą być zachowywane, tak jak byłoby to wymagane przy semantyce pełnego zamknięcia.) –
Jeśli to nie miało to miejsca, zmienne mogą być modyfikowane w dowolnym momencie bez ostrzeżenia. – jahroy