Здесь две реализации, которые используют замыкания и обратные вызовы.
А вот лучший пример (можно найти здесь http://www.caglargonul.com/2013/04/10/is-it-really-a-closure-yes-it-is/) для понимания того, что такое замыкание. Ключ в том, что
замыкание происходит со ссылочной средой, а не просто с кодом функции.
Лучший способ реализовать замыкание в Java 7 и ниже - использовать интерфейс. В этом примере обратный вызов реализован как замыкание.
Сначала вы объявляете свой интерфейс, который будет удерживать ваше закрытие.
public interface CallBack {
void m(int e);
}
И давайте добавим класс, отвечающий за хранение массива замыканий, два открытых метода для добавления и удаления замыканий и публичную функцию, которая будет вызывать функции внутри замыканий при возникновении события.
public class CCallBack {
List<CallBack> cbs = new ArrayList<>();
public void registerCallBack(CallBack f){
cbs.add(f);
}
public void removeCallBack(CallBack f){
if(cbs.contains(f)){
cbs.remove(f);
}
}
public void onAction(int i){
for (CallBack callBack : cbs) {
callBack.m(i);
}
}
}
А вот и волшебная часть. См. Ссылочную среду в действии.
public class CallBackTester {
CCallBack cb = new CCallBack();
@Test
public void test_callback(){
CallBack cb1 = new CallBack() {
int x = 1;
@Override
public void m(int e) {
if(e==1){
System.out.println("You register this callback " + x + " time/times");
x++;
}
}
};
cb.registerCallBack(cb1);
cb.registerCallBack(cb1);
cb.registerCallBack(cb1);
cb.removeCallBack(cb1);
cb.onAction(1);
}
}
Выше, когда мы объявляем cb1, мы добавляем среду ссылки, которая состоит из переменной x. Когда мы вызываем функцию внутри этого замыкания, мы увеличиваем эту переменную на единицу. Если бы это была нормальная функция, x был бы объявлен как 1, когда мы вызываем функцию. НО ЭТО НЕ НОРМАЛЬНАЯ ФУНКЦИЯ. ЭТО ЗАКРЫТИЕ. Поэтому x не объявляется каждый раз, когда мы вызываем функцию в замыкании. Как видно из выходных данных каждый раз, когда мы его вызываем, x увеличивается.
You register this callback 1 time/times
You register this callback 2 time/times