Java anonymous inner class and callback function

Java anonymous inner class and callback function

    The reason why the two knowledge points of anonymous inner class and callback function are written together is because I happened to encounter such an example when I was learning zookeeper recently. For details, please refer to: https://www.w3cschool.cn/zookeeper/zookeeper_api.html

The following is the complete code to connect to the ZooKeeper collection.

public class ZooKeeperConnection {

  //declare zookeeper instance to access ZooKeeper ensemble
   private ZooKeeper zoo;
   final CountDownLatch connectedSignal = new CountDownLatch(1);

  //Method to connect zookeeper ensemble.
   public ZooKeeper connect(String host) throws IOException,InterruptedException {
	
      zoo = new ZooKeeper(host,5000,new Watcher() {
		
         public void process(WatchedEvent we) {

            if (we.getState() == KeeperState.SyncConnected) {
               connectedSignal.countDown();
            }
         }
      });
		
      connectedSignal.await();
      return zoo;
   }

  //Method to disconnect from zookeeper server
   public void close() throws InterruptedException {
      zoo.close();
   }
} 

The creation format of the anonymous inner class is as follows:

new  |   
    {  
    //  
    } 

In the above code, the anonymous inner class is used when instantiating the ZooKeeper object in the connect method:

zoo = new ZooKeeper(host,5000,new Watcher() {
		
         public void process(WatchedEvent we) {

            if (we.getState() == KeeperState.SyncConnected) {
               connectedSignal.countDown();
            }
         }
      }); 

This inner class does not have its own name, but uses the Watcher interface. Normally, the interface cannot use new, but this can be done in anonymous inner classes. The class body of the anonymous inner class is a method named process, which is used to implement the process abstract method defined in the Watcher interface.


In this anonymous inner class, the callback function (also called the callback method) is used.

Callback is a common programming pattern. In this mode, you can point out the actions that should be taken when a particular event occurs. The ZooKeeper class provides the connect function through its constructor. The signature of the constructor is as follows: ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher) In the above class ZooKeeperConnection, the connect method creates a ZooKeeper object, connects to the ZooKeeper collection, and returns the object. CountDownLatch is used here to form a callback function. At the beginning, the connectedSignal value of the CountDownLatch object is set to CountDownLatch(1); if the if statement in the anonymous inner class is not true, it means that the main thread below will always be in a waiting state, staying at connectedSignal.await();. This fits the meaning of the callback function: the action that should be taken when a certain event occurs. If the client does not successfully establish a connection with Zookeeper (that is, if the if statement is not true), it does not return the ZooKeeper object zoo ( stay at connectedSignal.await()). Once the connection is successfully established (that is, if the if statement is true, the connectedSignal.countDown()) is executed , the ZooKeeper object zoo is returned ( connectedSignal.await() is released) and
the anonymous inner class is changed to the normal class. In the above code, the anonymous inner class can be changed. The class is disassembled as a separate class: XyzWatcher
public class XyzWatcher implements Watcher {
    @Override
    public void process(WatchedEvent watchedEvent) {
        final CountDownLatch connectedSignal = new CountDownLatch(1);
        if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
        try {
            connectedSignal.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
} 
The original class ZooKeeperConnection is changed to the following:
public class ZooKeeperConnection {

   //declare zookeeper instance to access ZooKeeper ensemble
    private ZooKeeper zoo;
   //public final CountDownLatch connectedSignal = new CountDownLatch(1);

   //Method to connect zookeeper ensemble.
    XyzWatcher xyz = new XyzWatcher();

    public ZooKeeper connect(String host) throws IOException,InterruptedException {
        zoo = new ZooKeeper(host,5000,xyz);
        return zoo;
    }

   //Method to disconnect from zookeeper server
    public void close() throws InterruptedException {
        zoo.close();
    }
}