您现在的位置是:首页 > 文章详情

Java匿名内部类与回调函数

日期:2018-06-29点击:388

    之所以将匿名内部类和回调函数两个知识点一起写,是因为最近学习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(); } }

原文链接:https://yq.aliyun.com/articles/604204
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章