— Привіт, Аміго! Ось тобі ще трохи інформації.
Я вже тобі казала, що всі анонімні класи насправді перетворюються компілятором на звичайні внутрішні класи.
— Ага. Я навіть пам'ятаю, що вони мають імена – це числа: 1, 2, 3 тощо.
— Саме так. Але ще який є нюанс.
Якщо клас був оголошений усередині методу та використовував якісь змінні, то посилання на них будуть додані до згенерованого класу. Дивись сам:
Було:
class Car
{
public ArrayList<Car> createPoliceCars(int count)
{
ArrayList<Car> result = new ArrayList<Car>();
for(int i=0; i<count; i++)
{
final int number = i;
result.add(new Car()
{
public String toString()
{
return ""+number;
}
});
}
return result;
}
}
Результат компіляції:
class Car
{
public ArrayList<Car> createPoliceCars(int count)
{
ArrayList<Car> result = new ArrayList<Car>();
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;
}
}
}
Зрозумів у чому штука? Внутрішній клас неспроможна змінити локальну змінну методу, т.к. на той час, коли буде виконуватися код цього класу, ми можемо взагалі піти з методу.
Тепер другий момент. Метод toString() використовує передану змінну. Для цього довелося:
А) зберегти її всередині згенерованого класу
Б) додати її до конструктора.
— Зрозумів. Класи, оголошені всередині методу, завжди працюють із копією змінних.
— Саме!
— Тоді зрозуміло, чому змінні мають бути final. І чому їх не можна міняти. Якщо насправді ти працюєш з копією, а не з оригіналом, то користувач не зрозуміє, чому не може змінювати значення змінної, а отже, треба просто заборонити її змінювати.
— Так, мені здається, що оголошення змінних final – це невелика плата за те, що компілятор за тебе згенерує клас, передасть у нього та збереже там усі змінні методи, які ти хочеш використати.
— Згоден. Все ж таки це крута штука – анонімні локальні класи.
А якщо я оголошу всередині методу свій локальний клас і використовуватиму в ньому змінні методи, компілятор їх теж додасть цьому класу?
— Так, додасть до класу та його конструктор.
— Я так і думав.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ