Есть ли какой-либо другой путь в Java для реализации спин вызова кроме внутренних классов? Каково различие между обратными вызовами и закрытиями?
Закрытие - это то, как вы его создаете, обратный вызов - это то, как вы его используете.
Обратный вызов может быть реализован как закрытие (в языках, где они есть) или как реализация интерфейса (в Java, как анонимный внутренний класс или обычный класс).
Обратный вызов означает, что вы передаете часть кода в функцию, чтобы функция могла вызвать эту часть кода позже. Это особый вид параметра.
Кусок кода может быть указателем функции, закрытием или объектом с известными методами, в зависимости от того, что предлагает язык.
Обратный вызов - это просто любой исполняемый код, который передается в качестве параметра другому коду. В частом употреблении этот исполняемый код является замыканием, но это не обязательно.
Словом "закрытие" несколько злоупотребляют, и многие используют его как синоним "анонимной функции", но, по крайней мере, согласно Википедии, это неправильное использование термина. Статья в Википедии объясняет это лучше, чем я могу сделать это быстро.
В качестве обратных вызовов можно использовать как замыкания, так и анонимные внутренние классы (и другие). Обратный вызов - это просто некоторый код, который передается в качестве аргумента другому коду.
Большое различие замыканий по сравнению с анонимными внутренними классами Java состоит в том, что (в императивных языках) замыкание может изменять переменные окружающей области видимости. Википедия дает следующий пример:
var f, g;
function foo() {
var x = 0;
f = function() { return ++x; };
g = function() { return --x; };
x = 1;
alert('inside foo, call to f(): ' + f()); // "2"
}
foo();
alert('call to g(): ' + g()); // "1"
alert('call to f(): ' + f()); // "2"
Я так не думаю.
Если есть, то он, вероятно, в чем-то хуже, иначе анонимные внутренние классы не получили бы широкого использования.
Нет никакой разницы.
Замыкания можно определить как блок кода, содержащий родительский контекст, который может быть легко выполнен.
На самом деле, единственное различие, которое я знаю между ними, - это легкость письма. Типичное замыкание groovy / ruby действительно меньше для написания, чем анонимный класс Java.
Однако, учитывая фреймворки Java, такие как guava , и широкое использование анонимных классов / интерфейсов, особенно для типичных случаев использования замыканий, таких как filter (по сравнению с реализацией Groovy ]), Я могу сказать, что абсолютно никакой разницы в дизайне нет.
На данный момент анонимные классы - лучший способ обработки обратных вызовов в Java. Однако это, вероятно, изменится, когда появится Java 7, в которой будут реализованы замыкания. http://en.wikipedia.org/wiki/Closure_ (computer_science)
К сожалению, единственный разумный способ - внутренние / анонимные классы.
Вы также можете сделать это с помощью отражения, но это обычно медленнее и сложнее в обслуживании (без подсветки синтаксиса, трудно найти ссылки в IDE и т. Д.). Пример:
myButton.addActionListener(EventHandler.create(ActionListener.class, handlerObject, "onClick"));
Если вам нужны замыкания в java, вы можете попробовать lambdaj . Здесь вы можете увидеть, как он позволяет определять замыкания через очень простой DSL.