В чём разница локального класса и анонимного класса?

Рейтинг: -1Ответов: 2Опубликовано: 17.08.2023

Подскажите, пожалуйста, в чём разница локального класса и анонимного класса, помимо того, что у анонимного класса нет названия. Когда какой нужно использовать?

Ответы

▲ 1Принят
  • Анонимный класс - это на самом деле скрытый локальный класс. Можно сказать, его упрощённая версия. Обычно, анонимные классы используются для того, чтобы переопределить метод(ы) из интерфейса/абстрактного класса для одноразового использования. И анонимный класс позволяет сделать это быстро и удобно:
AbstractClass ac = new AbstractClass() {
    @Override
    void doSomething() {
         //Реализация
    }
};
ac.doSomething();

Создавать локальный класс, потом его объект для такой простой цели смысла нет, это куча лишнего кода:

class LocalClass extends AbstractClass {
        @Override
        void doSomething() {
             //Реализация
        }
 }

LocalClass objectOfLocalClass = new LocalClass();
objectOfLocalClass.doSomething();
  • Локальные классы используются, когда вам нужен полноценный1 класс внутри метода:
public void someMethod(){
    class LocalClass() extends SomeClass implements Interface1, Interface2 {
        LocalClass(){
            //Код конструктора
        }

        //Методы
    }
    //Код метода someMethod()
}

1 локальные классы - конечно не совсем полноценные классы. А "под полноценным классом" я имею класс с наличием тех возможностей, которых нет у анонимных классов.

▲ 1

Локальные классы обычно применяются в следующих случаях:

  • создание экземпляра класса в методе более одного раза;
  • необходимость конструктора;
  • необходимость использования методов, расширяющих базовый класс.

Например:

Локальный класс

    public static void main(String[] args) {

        class MyLocalClass implements Runnable {
            private int value;
            private boolean isDone;

            public MyLocalClass(int value) {
                this.value = value;
            }

            @Override
            public void run() {
                while (value > 0) {
                    System.out.println(Thread.currentThread().getName() + ": " + value--);
                    LockSupport.parkNanos(300_000_000);
                }
                isDone = true;
                System.out.println(Thread.currentThread().getName() + " is done");
            }

            boolean isDone() {
                return isDone;
            }
        }

        var r1 = new MyLocalClass(10);
        var r2 = new MyLocalClass(20);

        new Thread(r1).start();
        new Thread(r2).start();

        while (!r1.isDone() && !r2.isDone()) {
            LockSupport.parkNanos(500_000_000);
        }

    }

Анонимный класс

public static void main(String[] args) {

    int value1 = 10;
    int value2 = 20;
    AtomicBoolean isDone1 = new AtomicBoolean(false);
    AtomicBoolean isDone2 = new AtomicBoolean(false);

    Runnable r1 = new Runnable() {

        @Override
        public void run() {
            int value = value1;
            while (value > 0) {
                System.out.println(Thread.currentThread().getName() + ": " + value--);
                LockSupport.parkNanos(300_000_000);
            }
            isDone1.set(true);
            System.out.println(Thread.currentThread().getName() + " is done");
        }
    };

    Runnable r2 = new Runnable() {

        @Override
        public void run() {
            int value = value2;
            while (value > 0) {
                System.out.println(Thread.currentThread().getName() + ": " + value--);
                LockSupport.parkNanos(300_000_000);
            }
            isDone2.set(true);
            System.out.println(Thread.currentThread().getName() + " is done");
        }
    };


    new Thread(r1).start();
    new Thread(r2).start();

    while (!isDone1.get() && !isDone2.get()) {
        LockSupport.parkNanos(500_000_000);
    }

}

Разница:

  • переиспользование кода в примере с анонимным классом;
  • параметры, передаваемые в конструктор в случае локального класса, берутся из замыкания в случае с анонимным классом;
  • примерно та же история с результатом, но вдобавок необходимо обеспечить свойство объектов isDoneХ как efficient final.