Как было замечено ранее, внутренние классы также могут создаваться в блоках кода — чаще всего в теле метода. Локальный внутренний класс не может иметь спецификатора доступа, так как он не является частью внешнего класса, но для него доступны все неизменные (final) переменные текущего блока и все члены внешнего класса. Следующий пример сравнивает процессы создания локального внутреннего класса и безымянного внутреннего класса:
//: innerclasses/LocalInnerClass.java
// Хранит последовательность объектов
import static net.mindview.util.Print.*;
interface Counter {
int next();
}
public class LocalInnerClass {
private int count = 0;
Counter getCounter(final String name) {
// Локальный внутренний класс:
class LocalCounter implements Counter {
public LocalCounter() {
// У локального внутреннего класса
// может быть собственный конструктор:
print("LocalCounter()");
}
public int next() {
printnb(name); // Access local final
return count++;
}
}
return new LocalCounter();
}
// To же самое с безымянным внутренним классом:
Counter getCounter2(final String name) {
return new Counter() {
// У безымянного внутреннего класса не может быть
// именованного конструктора, «легальна» только
// инициализация экземпляром:
{
print("Counter()");
}
public int next() {
printnb(name); // final аргумент
return count++;
}
};
}
public static void main(String[] args) {
LocalInnerClass lic = new LocalInnerClass();
Counter
c1 = lic.getCounter("Local inner "),
c2 = lic.getCounter2("Anonymous inner ");
for(int i = 0; i < 5; i++)
print(c1.next());
for(int i = 0; i < 5; i++)
print(c2.next());
}
}
<spoiler text="Output:">
LocalCounter()
Counter()
Local inner 0
Local inner 1
Local inner 2
Local inner 3
Local inner 4
Anonymous inner 5
Anonymous inner 6
Anonymous inner 7
Anonymous inner 8
Anonymous inner 9
</spoiler> Объект Counter возвращает следующее по порядку значение. Он реализован и как локальный класс, и как безымянный внутренний класс, с одинаковым поведением и характеристиками. Поскольку имя локального внутреннего класса недоступно за пределами метода, доводом для применения локального класса вместо безымянного внутреннего может быть необходимость в именованном конструкторе и (или) перегруженных конструкторах; безымянные внутренние классы допускают только инициализацию экземпляром. Другая причина для использования локального внутреннего класса вместо безымянного внутреннего — необходимость создания более чем одного объекта такого класса.