„Здравей, Амиго! Ето още информация за теб.“
„Вече ви казах, че компилаторът всъщност преобразува всички анонимни класове в обикновени вътрешни класове.“
"Да. Дори си спомням, че имената им са цифри: 1, 2, 3 и т.н."
— Точно така. Но тук има още един нюанс.
„Ако даден клас е деклариран в метод и използва някоя от своите променливи, тогава препратките към тези променливи ще бъдат добавени към генерирания клас. Вижте сами.“
„Започваме с това:“
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;
}
}
„И компилаторът генерира това:
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;
}
}
}
„Разбрахте ли смисъла? Вътрешният клас не може да промени локалната променлива на метода, защото докато се изпълни codeът на вътрешния клас, може да излезем от метода напълно.“
"Сега втората точка. Методът toString() използва предадена променлива. За да се постигне това, беше необходимо:"
A) запазете го вътре в генерирания клас
B) добавете го към конструктора.
„Разбрах. Класовете, декларирани в методите, винаги използват копия на променливи.“
"Точно!"
„Тогава има смисъл защо променливите трябва да са окончателни. И защо не могат да бъдат променяни. Ако всъщност работите с копия, а не с оригиналите, потребителят няма да разбере защо не може да променя стойностите на променливите, което означава, че трябва просто да му забраним да ги променя."
„Точно, декларирането на променливи като окончателни изглежда малка цена, която трябва да платите в замяна на това, че компилаторът генерира клас за вас, предава го на метода и запазва всички променливи на метода, които искате да използвате.“
„Съгласен съм. Анонимните местни класове все още са супер готини.“
„Ако декларирам локален клас вътре в метод и използвам променливите на метода в него, компилаторът ще ги добави ли също към класа?“
„Да, ще ги добави към класа и неговия конструктор.“
"Това е, което си мислех."
GO TO FULL VERSION