Co naprawdę się dzieje (tj. co kompilator generuje z klas) - 1

"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:”

przed kompilacją:
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:

Po skompilowaniu:
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."