Механизм обратного вызова(callbacks) широко распространен в программировании. При обратном вызове программист задает действия, которые должны выполняться всякий раз, когда происходит некоторое событие. И неважно, будете разрабатывать только java-программы или android-приложения — колбеки будут встречаться вам повсюду.
Для создания методов обратного вызова (callback) в java используются уже знакомые нам из прошлого урока интерфейсы.
Создадим новый класс SomeClass с интерфейсом Callback:
import javax.swing.*;
public class SomeClass {
// создаем колбек и его метод
interface Callback{
void callingBack();
}
Callback callback;
public void registerCallBack(Callback callback){
this.callback = callback;
}
void doSomething(){
JOptionPane.showMessageDialog(null, "Выполняется работа");
// вызываем метод обратного вызова
callback.callingBack();
}
}
У интерфейса мы определили один метод callingBack(). Далее в классе мы создали объект интерфейса и инициализировали его в методе registerCallBack. В классе также был создан метод doSomething(), в котором может содержаться какой-то сложный код. Мы здесь создаем диалоговое окно, используя компонент JOptionPane библиотеки Swing. Кто не в курсе, Swing — библиотека для создания графического интерфейса программ на языке Java.
В конце работы метода doSomething() вызывается метод интерфейса callingBack() . В данном случае мы сами создали метод и знаем его код. Но во многих случаях, вы будете использовать готовый метод какого-то класса и можете даже не знать, что именно содержится в этом методе. Вам надо только знать, что такой метод существует и выполняет конкретную задачу.
Теперь нам нужен класс, реализующий интерфейс-callback. Создаем класс MyClass и подключаем интерфейс-колбек через ключевое слово implements. Среда разработки заставит нас реализовать шаблон метода интерфейса.
public class MyClass implements SomeClass.Callback {
@Override
public void callingBack() {
System.out.println("Вызов метода обратного вызова");
}
}
Теперь мы можем использовать метод обратного вызова callingBack () для решения своих задач. Будем здесь выводить текст в консоль. Создадим класс Main, в котором будет реализован метод main — точка входа в программу.
public class Main {
public static void main(String[] args) {
SomeClass someClass = new SomeClass();
MyClass myClass = new MyClass();
//инициализируем колбек, передавая методу registerCallBack экземпляр MyClass, реализующий интерфейс колбек
someClass.registerCallBack(myClass);
someClass.doSomething();
}
}
Здесь создаем экземпляры классов, инициализируем колбек, передавая методу registerCallBack экземпляр MyClass, реализующий интерфейс-callback. И вызываем метод doSomething();
При старте программы будет выполняться код метода doSomething(); из класса SomeClass. На экране появилось диалоговое окно.

Когда мы нажмем кнопку, или закроем диалоговое окно, сработает метод обратного вызова callingBack(), который выведет сообщение в консоль.
Через интерфейс-callback также можно передавать какие-то данные. Давайте немного усложним пример.
package callback;
import javax.swing.*;
public class SomeClass {
String replyTo;
interface Callback{
void callingBack(String s);
}
private Callback callback;
public void registerCallBack(Callback callback){
this.callback = callback;
}
void doSomething(){
int reply = JOptionPane.showConfirmDialog(null, "Вы программист?", "Опрос", JOptionPane.YES_NO_OPTION);
if (reply == JOptionPane.NO_OPTION){
replyTo = "Нет";
}
if (reply == JOptionPane.YES_OPTION){
replyTo = "Да";
}
callback.callingBack(replyTo);
}
}
Объявим строковую переменную replyTo. Добавим аргумент метода callingBack — строковую переменную.
Изменим диалоговое окно — присвоим его новой целочисленной переменной reply, и изменим на showConfirmDialog, который имеет заголовок окна и больше одной кнопки ответа. В зависимости от нажатой кнопки переменной reply будет присвоено значение. Сравниваем ее значение с константой и присваиваем значение «Да» или «Нет» переменной replyTo.
Теперь внесем изменения в MyClass.
package callback;
public class MyClass implements SomeClass.Callback {
@Override
public void callingBack(String s) {
if (s != null) {
System.out.println("Ваш ответ: " + s);
} else {
System.out.println("Вы не ответили на вопрос!");
}
}
}
Добавим аргумент в метод. И добавим условие проверки, что строка не пустая — это возможно, если вместо ответа просто закрыть диалоговое окно.
Класс Main без изменений.
package callback;
public class Main {
public static void main(String[] args) {
SomeClass someClass = new SomeClass();
MyClass myClass = new MyClass();
someClass.registerCallBack(myClass);
someClass.doSomething();
}
}
Запускаем программу. Теперь текст сообщения в консоли меняется в зависимости от того, выберем мы да, нет или просто закроем окно.

Я надеюсь, вы поняли принцип методов обратного вызова. Ниже есть ссылка на дополнительную информацию по колбекам, а также более сложные и познавательные примеры. Вопросы можно задавать в комментариях.
<<Предыдущий урок Следующий урок>>
AndroidStudio ругается на JOptionPane. Можно ли как-то это исправить?
Аналогично… Но ответа видимо нет…