Подтвердить что ты не робот

Какая разница между анонимными классами в Java и закрытием?

Похоже, что анонимный класс предоставляет базовые функции закрытия, это правда?

4b9b3361

Ответ 1

Насколько они влияют в противном случае "private", в очень ограниченном смысле, да. тем не менее, существует так много различий, что ответ также может быть отрицательным.

Поскольку Java не имеет возможности обрабатывать блоки кода как истинные значения R, внутренние классы не могут передавать блоки кода, как это обычно делается в продолжениях. Поэтому закрытие как техника продолжения полностью отсутствует.

В то время как время жизни класса, собираемого для сбора мусора, расширяется людьми, занимающимися внутренними классами (аналогично закрытию, сохраняющим переменные, когда они восстанавливаются до закрытия), способность Java выполнять переименование посредством привязки ограничивается соблюдением существующий синтаксис Java.

И чтобы позволить потокам правильно не топать друг над другом данными с использованием модели конфликтов Java-потоков, внутренние классы дополнительно ограничены доступом к данным, которые гарантированно не расстраиваются, а также конечные локали.

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

Ответ 2

Нет почти никакой разницы. На самом деле есть старая поговорка о закрытии и объектах. Закрытие - это объект бедного человека, а объекты - закрытие бедных людей. Оба они одинаково сильны в плане того, что они могут сделать. Мы только спорим о выразительности.

В Java мы моделируем закрытие с помощью Анонимных объектов. На самом деле небольшая история здесь заключается в том, что изначально у Java была возможность изменять внешний охват без использования final. Это работает и отлично работает для объектов, выделенных в области локального метода, но когда дело доходит до примитивов, это вызвало много споров. Примитивы выделяются в стеке, поэтому для того, чтобы они могли жить после выполнения внешнего метода, Java должен был бы выделить память в куче и переместить эти члены в кучу. В то время люди были очень новы для сбора мусора, и они не доверяли ему, поэтому претензия Java не должна выделять память без явной инструкции от программиста. В попытке найти компромиссное решение Java решило использовать последнее ключевое слово.

http://madbean.com/2003/mb2003-49/

Теперь интересно то, что Java может удалить это ограничение и использовать последнее ключевое слово опционально, теперь все более комфортно с сборщиком мусора, и он может быть полностью совместим с точки зрения языка. Хотя работа вокруг этой проблемы проста, чтобы определить переменные экземпляра на вашем анонимном объекте, и вы можете изменить их столько, сколько пожелаете. На самом деле это может быть простой способ реализовать ссылки на стиль замыкания на локальную область, добавив переменные общего экземпляра в анонимный класс через компилятор и переписывая исходный код, чтобы использовать их вместо переменных стека.

public Object someFunction() {
   int someValue = 0;

   SomeAnonymousClass implementation = new SomeAnonymousClass() {
       public boolean callback() {
           someValue++;
       }
   }
   implementation.callback();
   return someValue;
}

Будет переписан на:

 public Object someFunction() {
   SomeAnonymousClass implementation = new SomeAnonymousClass() {
       public int someValue = 0;

       public boolean callback() {
           someValue++;
       }
   }
   implementation.callback();

   // all references to someValue could be rewritten to 
   // use this instance variable instead.
   return implementation.someValue;
}

Я думаю, что причина, по которой люди жалуются на анонимные внутренние классы, больше связана со статической типизацией и динамической типизацией. В Java мы должны определить согласованный интерфейс для разработчика анонимного класса и код, принимающий анонимный класс. Мы должны сделать это, чтобы мы могли набрать все во время компиляции. Если бы у нас были функции первого класса, то Java необходимо было бы определить синтаксис для объявления параметров метода и возвращаемых типов в качестве типа данных, чтобы оставаться статически типизированным языком для безопасности типов. Это будет почти таким же сложным, как определение интерфейса. (Интерфейс может определять несколько методов, синтаксис для объявления методов первого класса будет только для одного метода). Вы могли бы подумать об этом как о синтаксисе интерфейса короткой формы. Под капотом компилятор мог преобразовать краткую нотацию формы в интерфейс во время компиляции.

Есть много вещей, которые можно было бы сделать для Java, чтобы улучшить класс анонимного класса, не прерывая язык или большую операцию.

Ответ 3

IMHO, они выполняют аналогичную цель, однако закрытие должно быть более кратким и потенциально обеспечивать большую функциональность.

Предположим, вы хотите использовать локальную переменную, используя анонимный класс.

final int[] i = { 0 };
final double[] d = { 0.0 };

Runnable run = new Runnable() { 
    public void run() {
        d[0] = i[0] * 1.5;
    }
};
executor.submit(run);

Закрытие предотвращает необходимость в большинстве кодовых табличек котлов, позволяя вам писать именно то, что предназначено.

int i = 0;
double d = 0.0;

Runnable run = { => d = i * 1.5; };
executor.submit(run);

или даже

executor.submit({ => d = i * 1.5; });

или если блокировки поддерживают блоки кода.

executor.submit() {
    d = i * 1.5; 
}