Раньше я занимался разработкой на Java и не до конца понимал концепцию обратного вызова, пока не начал программировать на C # и его делегатах.
Причина этого в том, что, как @Denilson Sá прекрасно упомянул, Java не использует Javaуказатели на функции.Другими словами, в Java вы можете вызывать метод и передавать некоторые аргументы, такие как примитивные значения (int, long, char, boolean и т. Д.) И объекты (String или любой экземпляр любого класса, например, когда вы передаете объект, вы в основномпередача адреса в память реального объекта, который живет где-то в памяти).
Концепция обратного вызова в Java может быть реализована с использованием интерфейсов и передачи их (объект, который их реализует) в качестве аргументов.Представьте, что у вас есть следующий интерфейс, который определяет 2 метода, которые ЛЮБОЙ класс, который хочет вести себя как ResultListener, должен реализовать.
interface ResultListener {
void onSuccessOperation(String description);
void onFailedOperation(String description);
}
Теперь представьте, что у вас есть основная программа, которая работает внутри showScreen method
class MyMainScreen implements ResultListener {
public void showScreen() {
//do some things..
SmartClass smartClass = new SmartClass();
smartClass.divideAndNotify(5, 0, this);
}
public void onSuccessOperation(String description) {
System.out.println("SUCCESS!!. " + description);
}
public void onFailedOperation(String description) {
System.out.println("FAILED. " + description);
}
}
И это SmartClass, который знает, как делить.
class SmartClass {
public void divideAndNotify(int numerador, int denominador, ResultListener resultListener) {
if (denominador == 0) {
resultListener.onFailedOperation("Nobody can divide by zero!!");
} else {
int total = numerador / denominador;
resultListener.onSuccessOperation("The result is " + total);
}
}
}
Интересно, что MyMainScreen ведет себя как ResultListener, поэтому ему нужно реализовать методыопределяется в интерфейсе ResultListener.MyMainScreen знает, как печатать сообщения на консоли, но он ничего не знает о вычислениях, и именно поэтому он создает экземпляр SmartClass, чтобы использовать его методdivAndNotify, который принимает 2 числа и ссылку на экземпляр, который будет прослушивать результат (в нашемв данном случае этот экземпляр является самим экземпляром MyMainScreen, и поэтому он передает себя со словом this )
Метод SmartClassdivAndNotify знает математику и уведомляет любого, кто слушает, о результате операции.,Его метод знает, что resultListener будет содержать ссылку на объект, который знает, что делать, если результат успешен или неуспешен.
Концепция обратного вызова здесь заключается в том, что SmartClass делегирует функциональность того, что делать с результатом,это похоже на «обратный вызов» чего-либо в экземпляре, который он получил в качестве параметра.
Как итог: обратный вызов - это просто ДЕЛЕГАЦИЯ задачи.
PS: С C # эта концепция намного проще, потому что C # имеет типы делегатов, которые являются переменными, которые хранят адреса памяти, где находятся функции (функции, которые хранят, должны соответствовать сигнатуре, определенной в делегате).