Java匿名内部类与回调函数

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介:     之所以将匿名内部类和回调函数两个知识点一起写,是因为最近学习zookeeper的时候正好遇到这么一个例子。详细内容请参考:https://www.w3cschool.cn/zookeeper/zookeeper_api.html 以下是与ZooKeeper集合连接的完整代码。

    之所以将匿名内部类和回调函数两个知识点一起写,是因为最近学习zookeeper的时候正好遇到这么一个例子。详细内容请参考:https://www.w3cschool.cn/zookeeper/zookeeper_api.html

以下是与ZooKeeper集合连接的完整代码。

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();
   }
}

匿名内部类的创建格式如下:

new 父类构造器(参数列表)|实现接口()  
    {  
     //匿名内部类的类体部分  
    }

在上面的代码中,connect方法中在实例化ZooKeeper对象时用到了匿名内部类:

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

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

这个内部类没有自己的名字,而是用到了Watcher接口,而通常情况下接口是不能用new的,但是在匿名内部类中可以这样。匿名内部类的类体是一个名为process的方法,这个方法就是用来实现Watcher接口中定义的process抽象方法的。


在这个匿名内部类中恰好又运用了回调函数(又叫回调方法)。

回调是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。
ZooKeeper类通过其构造函数提供connect功能。构造函数的签名如下 : ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)
在上面的类ZooKeeperConnection中,connect 方法创建一个ZooKeeper对象,连接到ZooKeeper集合,然后返回对象。
在此处使用CountDownLatch,就是为了形成一个回调函数。一开始将CountDownLatch对象connectedSignal值设为CountDownLatch(1);如果匿名内部类中的if语句不为真,这意味着下面的主线程会在一直处于等待状态,停留在connectedSignal.await();处。这个就恰好符合了回调函数的意义:
在某个特定事件发生时应该采取的动作。
如果客户端与Zookeeper没有成功建立连接(也就是if语句不为真),就不返回ZooKeeper对象zoo(在 connectedSignal.await()停留)。而一旦成功建立连接 (也就是if语句为真,执行connectedSignal.countDown()),就返回 ZooKeeper对象zoo ( connectedSignal.await()放行)

将匿名内部类改为普通类
在上述代码中可以将匿名内部类拆出来,作为一个单独类: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();
        }
    }
}
原来的类ZooKeeperConnection改为如下:
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();
    }
}

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
7天前
|
Java
【Java基础】 内部类 (成员内部类、局部内部类、静态内部类、匿名内部类)
Java内部类 (成员内部类、局部内部类、静态内部类、匿名内部类)
5 0
|
15天前
|
Java
【Java探索之旅】内部类 静态、实例、局部、匿名内部类全面解析
【Java探索之旅】内部类 静态、实例、局部、匿名内部类全面解析
11 0
|
29天前
|
Java
Java 匿名内部类
Java 匿名内部类
6 1
|
7月前
|
Java
java匿名内部类
java匿名内部类
|
29天前
|
JavaScript 前端开发 Java
Java Script中的回调函数,可以用来做什么
Java Script中的回调函数,可以用来做什么
13 0
|
10月前
java202303java学习笔记第二十四天-匿名内部类3
java202303java学习笔记第二十四天-匿名内部类3
26 0
|
11月前
|
Java 编译器
【Java面试】为什么匿名内部类只能访问外部类的final类型局部变量?
【Java面试】为什么匿名内部类只能访问外部类的final类型局部变量?
104 0
|
11月前
|
Java
什么是java回调函数
什么是java回调函数
117 1
什么是java回调函数
|
29天前
|
Java 程序员
java回调函数
java回调函数
40 0
|
29天前
|
Java
Java中的匿名内部类(看这篇就够了)
Java中的匿名内部类(看这篇就够了)
456 0