科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java 5.0的五个特性1

Java 5.0的五个特性1

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

至今,毫无疑问你已经看过不止一篇网上文章列举了Java5.0的伟大的语言新特性:泛型,标注,枚举类型,自动装箱,可变参数, for/in循环,甚至静态引入。在此我将集中于你可能没有听说过的Java5.0的新API特性。

来源:IT专家网 2008年5月31日

关键字: 特性 java

  • 评论
  • 分享微博
  • 分享邮件
至今,毫无疑问你已经看过不止一篇网上文章列举了Java5.0的伟大的语言新特性:泛型,标注,枚举类型,自动装箱,可变参数, for/in循环,甚至静态引入。我也认为这些是伟大的特性,但是,你已经读过他们了。因此,在此我将集中于你可能没有听说过的Java5.0的新API特性。

  那么,在下面,是我喜欢的Java5.0的五个新API特性。那些看完本文后的细心的读者会发现额外的奖励—第六个特性:很少有人知道的Java5.0支持的新语言语法,当然使用者就更少了。我非常喜欢它,因为它很新异。

  Callable 和 Future 接口

  我喜欢的第一个特性发掘自新的java.util.concurrent包。如它的名字暗示的,这是个并行编程工具包。在此有很多要探索的,而我要提的第一喜欢的特性是TimeUnit枚举类型。TimeUnit让我感兴趣的是它包含有用的时间相关工具--你通过一个枚举常量来调用它们,该常量代表度量时间的单位。例如:

TimeUnit.MILLISECONDS.sleep(200);

  然而,TimeUnit并不是最值得夸奖的。java.util.concurrent最强大的特性之一是它的任务-执行/线程-池结构。ExecutorService接口提供了执行任务的能力。Executors类定义了工厂方法用于获取使用线程池的ExecutorService的实现。这是强大的要素。

  我所喜欢的任务-执行框架的部分是它如何表现任务以及执行它的结果:Callable和Future接口。我们都熟悉用于定义线程的Runnable接口和它的run()方法。Callable像Runnable,但它的方法叫做call(),并且这个方法可以返回一个结果或者抛出一个异常,而这两点是Runnable.run()做不到的。

  Callable是一个泛型,并且它的结果已经参数化。例如,一个计算BigInteger的任务,是Callable<BigInteger>,并且它的方法call()被声明为返回BigInteger。下面是仅有三行代码的Callable接口:

public interface Callable<V> {
      V call() throws Exception;
  }

  当我想要异步执行一个Callable任务,我将它传递给ExecutorService的submit()方法。submit()的返回值—这也是我喜欢的部分—是一个Future对象:本质上是一个对将来某时刻的结果的“借条”。如果我准备使用我的任务的结果,我简单的调用Future对象的get()方法即可。如果任务的执行已完成,那么get()立刻返回结果。否则,它将阻塞直到结果可用。如果Callable抛出异常,那么get()方法将该异常包装为ExecutionException并且抛出它。Future还有方法用来对任务的执行进行取消和查询状态,但是你必须自己查找它们(这些方法)。Future也用了泛型,并且结果的类型也参数化了。因此如果我submit()一个Callable<BigInteger>来执行,我将获得一个Future< BigInteger >。

  下面是一个简短的例子:

/**
 * 这是一个用来计算大素数的Callable。
 */
public class PrimeSearch implements Callable<BigInteger>
{
    static Random prng = new SecureRandom();
    int n;
    public PrimeSearch(int bitsize) { n = bitsize; }
    public BigInteger call() {
        return BigInteger.probablePrime(n, prng);
    }
}

// 尝试同时计算两个素数
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<BigInteger> p = pool.submit(new PrimeSearch(512));
Future<BigInteger> q = pool.submit(new PrimeSearch(512));

// 将两个素数相乘来得到一个合数
BigInteger product = p.get().multiply(q.get());

可变参数和自动装箱

  我说过我不想谈论Java5.0的新语言特性,我不会,但是我确实关注由于可变参数和自动装箱才变为可能的(或者被增强的旧API)新的API。

  首先,当然,是Java5.0的printf风格的文本格式化能力,通过java.util.Formatter类和类似String.format()的工具方法。这类文本格式化是最常被引用来支持语言的增加的可变参数和自动装箱的那种用例。考虑这个:

String s = String.format("%s:%d: %s%n", filename,
                           lineNumber,
                   exception.getMessage());

  关于这段代码没有什么特别值得注意的东西。我将它列在这是为了说明因为可变参数和自动装箱所以比下面的例子显得简单:

String s = String.format("%s:%d: %s%n", new Object[] {
                           filename,
                           new Integer(lineNumber),
              exception.getMessage()});

  可变参数和自动装箱还对java.lang.reflect API有一个实质性的影响。那就是当查找和调用方法时不再需要类和对象数组:

Method m = c.getMethod("put", Object.class,Object.class);
  m.invoke(map, "key", "value");

  如果我必须选择一个最喜欢的可变参数方法,那么,将是java.util.Arrays.asList()。这个方法真是个用于创建不变的对象列表的方便的工厂方法。它接受任何数量的类型T的参数并且将它们作为List返回:

List<Integer> smallPrimes =
     Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19);

  能力

  我们在上面谈论了Runnable和Callable,并且你毫无疑问已经听说过重要的Comparable, Serializable,和Cloneable接口。Java5.0新增加了五个重要的能力接口。第一个,当然,是java.lang.Iterable。你或许知道Java5.0新的for/in循环可以迭代数组和集合。你可能不知道它能够对任何实现了可迭代(Iterable)接口的对象工作。因此,如果你想让一个不是集合的数据结构可以简单地迭代,只需实现Iterable接口。你要做的就是增加一个返回java.util.Iterator 的iterator()方法。当然,写这个迭代器(Iterator)可能不是那么简单的。

  下面的代码是一个实现了Iterable<String>(是的,Iterable是泛型的)的文本文件类,因而允许文本文件可以用for/in循环逐行的迭代。你可以用类似下面的代码使用它:

TextFile textfile = new TextFile(new File(f), "UTF-8");
  int lineNumber = 0;
  for(String line : textfile)
      System.out.printf("%6d: %s%n", ++lineNumber, line);

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章