首页 | 源码下载 | 网站模板 | 网页特效 | 广告代码 | 网页素材 | 字体下载 | 书库 | 站长工具
会员投稿 投稿指南 RSS订阅
当前位置:主页>网络编程>java教程>资讯:面向Java开发人员的Scala指南: 增强Scitter库

面向Java开发人员的Scala指南: 增强Scitter库

www.jz123.cn  2009-09-03   来源:   IT专家网    责任编辑(袁袁)    我要投递新闻

 兼容性

  但是,这又产生一个有趣的问题:从 Java 代码调用这个方法有多容易?毕竟,如果这个库的主要目标之一是维护与 Java 代码的兼容性,那么我们需要确保 Java 代码在使用它时不至于太麻烦。

  我们首先通过我们的好朋友 javap 检验一下 Scitter 类:

  清单 10. 哦,没错,Java 代码……我现在想起来了……

 


 C:>javap -classpath classes com.tedneward.scitter.Scitter
  Compiled from "scitter.scala"
  public class com.tedneward.scitter.Scitter extends java.lang.Object implements s
  cala.ScalaObject{
  public com.tedneward.scitter.Scitter(java.lang.String, java.lang.String);
  public scala.List friendsTimeline(scala.Seq);
  public boolean verifyCredentials();
  public int $tag() throws java.rmi.RemoteException;
  }

  这时我心中有两点担心。首先,friendsTimeline() 带有一个 scala.Seq 参数(这是我们刚才用过的重复参数特性)。其次,friendsTimeline() 方法和 Scitter 对象中的 publicTimeline() 方法一样(如果不信,可以运行 javap 查证),返回一个元素列表 scala.List.这两种类型在 Java 代码中有多好用?

  最简单的方法是用 Java 代码而不是 Scala 编写一组小型的 JUnit 测试,所以接下来我们就这样做。虽然可以测试 Scitter 实例的构造,并调用它的 verifyCredentials() 方法,但这些并不是特别有用 — 记住,我们不是要验证 Scitter 类的正确性,而是要看看从 Java 代码中使用它有多容易。为此,我们直接编写一个测试,该测试将获取 “friends timeline” — 换句话说,我们要实例化一个 Scitter 实例,并且不使用任何参数来调用它的 friendsTimeline() 方法。

  这有点复杂,因为需要传入 scala.Seq 参数 — scala.Seq 是一个 Scala 特性,它将映射到底层 JVM 中的一个接口,所以不能直接实例化。我们可以尝试典型的 Java null 参数,但是这样做会在运行时抛出异常。我们需要的是一个 scala.Seq 类,以便从 Java 代码中轻松地实例化这个类。

  最终,我们还是在 mutable.ListBuffer 类型中找到一个这样的类,这正是在 Scitter 实现本身中使用的类型:

  清单 11. 现在我明白了自己为什么喜欢 Scala……

 


 package com.tedneward.scitter.test;
  import org.junit.*;
  import com.tedneward.scitter.*;
  public class JavaScitterTests
  {
  public static final String testUser = "TESTUSER";
  public static final String testPassword = "TESTPASSWORD";
  @Test public void getFriendsStatuses()
  {
  Scitter scitter = new Scitter(testUser, testPassword);
  if (scitter.verifyCredentials())
  {
  scala.List statuses =
  scitter.friendsTimeline(new scala.collection.mutable.ListBuffer());
  Assert.assertTrue(statuses.length() > 0);
  }
  else
  Assert.assertTrue(false);
  }
  }

  使用返回的 scala.List 不是问题,因为我们可以像对待其他 Collection 类一样对待它(不过我们的确怀念 Collection 的一些优点,因为 List 上基于 Scala 的方法都假设您将从 Scala 中与它们交互),所以,遍历结果并不难,只要用上一点 “旧式” Java 代码(大约 1995 年时候的风格):

  清单 12. 重回 1995,又见 Vector……


     package com.tedneward.scitter.test;
  import org.junit.*;
  import com.tedneward.scitter.*;
  public class JavaScitterTests
  {
  public static final String testUser = "TESTUSER";
  public static final String testPassword = "TESTPASSWORD";
  @Test public void getFriendsStatuses()
  {
  Scitter scitter = new Scitter(testUser, testPassword);
  if (scitter.verifyCredentials())
  {
  scala.List statuses =
  scitter.friendsTimeline(new scala.collection.mutable.ListBuffer());
  Assert.assertTrue(statuses.length() > 0);
  for (int i=0; i 
  {
  Status stat = (Status)statuses.apply(i);
  System.out.println(stat.user().screenName() + " said " + stat.text());
  }
  }
  else
  Assert.assertTrue(false);
  }
  }

  这将我们引向另一个部分,即将参数传递到 friendsTimeline() 方法。不幸的是,ListBuffer 类型不是将一个集合作为构造函数参数,所以我们必须构造参数列表,然后将集合传递到方法调用。这样有些单调乏味,但还可以承受:

  清单 13. 现在可以回到 Scala 吗?


  package com.tedneward.scitter.test;
  import org.junit.*;
  import com.tedneward.scitter.*;
  public class JavaScitterTests
  {
  public static final String testUser = "TESTUSER";
  public static final String testPassword = "TESTPASSWORD";
  // ...
  @Test public void getFriendsStatusesWithCount()
  {
  Scitter scitter = new Scitter(testUser, testPassword);
  if (scitter.verifyCredentials())
  {
  scala.collection.mutable.ListBuffer params =
  new scala.collection.mutable.ListBuffer();
  params.$plus$eq(new Count(5));
  scala.List statuses = scitter.friendsTimeline(params);
  Assert.assertTrue(statuses.length() > 0);
  Assert.assertTrue(statuses.length() == 5);
  for (int i=0; i 
  {
  Status stat = (Status)statuses.apply(i);
  System.out.println(stat.user().screenName() + " said " + stat.text());
  }
  }
  else
  Assert.assertTrue(false);
  }
  }

  所以,虽然 Java 版本比对应的 Scala 版本要冗长一点,但是到目前为止,从任何要使用 Scitter 库的 Java 客户机中调用该库仍然非常简单。好极了。

  结束语

  显然,对于 Scitter 还有很多事情要做,但是它已经逐渐丰满起来,感觉不错。我们设法对 Scitter 库的通信部分进行了 DRY 化处理,并且为 Twitter 提供的很多不同的 API 调用合并了所需的可选参数 — 到目前为止,Java 客户机基本上没有受到我们公布的 API 的拖累。即使 API 没有 Scala 所使用的那些 API 那样干净,但是如果 Java 开发人员要使用 Scitter 库,也不需要费太多力气。

  Scitter 库仍然带有对象的意味,不过我们也开始看到,一些有实用意义的 Scala 特性正在出现。随着我们继续构建这个库,只要有助于使代码更简洁、更清晰,越来越多这样的特性将添加进来。本应如此。

  是时候说再见了,我要短暂离开一下。等我回来时,我将为这个库增加对离线测试的支持,并增加更新用户状态的功能。到那时,Scala 迷们,请记住:功能正常总比功能失常好。(对不起,我只是太喜欢开玩笑了。)

上一篇:Java Math 类中的新功能(一): 实数 下一篇:通过Java或Jsp向数据库存取二进制图片

评论总数:0 [ 查看全部 ] 网友评论


关于我们隐私版权广告服务友情链接联系我们网站地图