
"Cześć, Amigo! Oto więcej informacji dla ciebie."
„Mówiłem już, że kompilator faktycznie konwertuje wszystkie anonimowe klasy na zwykłe klasy wewnętrzne”.
„Tak. Pamiętam nawet, że ich imiona to cyfry: 1, 2, 3 itd.”
„Dokładnie. Ale jest tu jeszcze jeden niuans”.
„Jeśli klasa jest zadeklarowana wewnątrz metody i używa którejkolwiek z jej zmiennych, to referencje do tych zmiennych zostaną dodane do wygenerowanej klasy. Przekonaj się sam”.
„Zaczynamy od tego:”
class Car
{
public ArrayList createPoliceCars(int count)
{
ArrayList result = new ArrayList();
for(int i = 0; i < count; i++)
{
final int number = i;
result.add(new Car()
{
public String toString()
{
return ""+number;
}
});
}
return result;
}
}
„A kompilator generuje to:
class Car
{
public ArrayList createPoliceCars(int count)
{
ArrayList result = new ArrayList();
for(int i = 0; i < count; i++)
{
final int number = i;
result.add(new Anonymous2 (number));
}
return result;
}
class Anonymous2
{
final int number;
Anonymous2(int number)
{
this.number = number;
}
public String toString()
{
return ""+ number;
}
}
}
„Zrozumiałeś? Klasa wewnętrzna nie może zmienić zmiennej lokalnej metody, ponieważ zanim kod klasy wewnętrznej zostanie wykonany, możemy całkowicie wyjść z metody”.
„Teraz druga kwestia. Metoda toString() wykorzystuje przekazaną zmienną. Aby to osiągnąć, konieczne było:”
A) zapisz go w wygenerowanej klasie
B) dodaj go do konstruktora.
— Rozumiem. Klasy zadeklarowane wewnątrz metod zawsze używają kopii zmiennych.
"Dokładnie!"
„W takim razie ma sens, dlaczego zmienne muszą być ostateczne. I dlaczego nie można ich zmienić. Jeśli faktycznie pracujesz z kopiami, a nie oryginałami, użytkownik nie zrozumie, dlaczego nie może zmieniać wartości zmiennych, co oznacza, że musimy po prostu zabronić mu ich zmiany”.
„Racja, zadeklarowanie zmiennych jako ostateczne wydaje się niewielką ceną do zapłacenia w zamian za wygenerowanie przez kompilator klasy, przekazanie jej do metody i zapisanie wszystkich zmiennych metody, których chcesz użyć”.
„Zgadzam się. Anonimowe zajęcia lokalne są nadal super fajne”.
„Jeśli zadeklaruję lokalną klasę wewnątrz metody i użyję w niej zmiennych metody, czy kompilator doda je również do klasy?”
„Tak, doda je do klasy i jej konstruktora”.
"Tak myślałem."
GO TO FULL VERSION