科技行者

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

知识库

知识库 安全导航

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

Java 5.0的五个特性2

  • 扫一扫
    分享文章到微信

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

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

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

关键字: 特性 Java 5 java

  • 评论
  • 分享微博
  • 分享邮件
下面是TextFile的代码。注意,迭代器不尝试检测对底层文件的并发的修改。如果你想自己做,看一看

java.nio.channels.FileLock。
import java.io.*;
import java.util.Iterator;

public class TextFile implements Iterable<String> {
    File f;
    String charsetName;

    public TextFile(File f, String charsetName)
   throws IOException
    {
   this.f = f;
   this.charsetName = charsetName;

   if (!f.exists())
       throw new FileNotFoundException(f.getPath());
   if (!f.canRead())
       throw new IOException("Can't read: " +
              f.getPath());
    }

    public Iterator<String> iterator() {
   try {
       return new TextFileIterator(f, charsetName);
   }
   catch(IOException e) {
       throw new IllegalArgumentException(e);
   }
    }


    static class TextFileIterator
   implements Iterator<String>
    {
   BufferedReader in;
   String nextline;
   boolean closed = false;

   public TextFileIterator(File f, String charsetName)
       throws IOException
   {
       InputStream fis = new FileInputStream(f);
       Reader isr =
      new InputStreamReader(fis, charsetName);
       in = new BufferedReader(isr);
       getNextLine();
   }

   public boolean hasNext() {
       return nextline != null;
   }

   public String next() {
       String returnValue = nextline;
       getNextLine();
       return returnValue;
   }

   public void remove() {
       throw new UnsupportedOperationException();
   }

   void getNextLine() {
       if (!closed) {
      try { nextline = in.readLine(); }
      catch(IOException e) {
          throw new IllegalArgumentException(e);
      }
      if (nextline == null) {
          try { in.close(); }
          catch(IOException ignored) {}
          closed = true;
      }
       }
   }
    }
}

Iterable是到目前为止最重要的新能力接口,但是其它的也是非常的漂亮。接下来,我们碰到java.lang.Appendable。一个Appendable对象可以追加字符或字符序列(或者一个字符序列的子序列)。实现者包括StringBuffer和StringBuilder(如果你还没有听说过它,一定要看一看),Writer(及其子类),PrintStream,还有java.nio.CharBuffer。将可追加性从这些类中分离出来成为Appendable接口,使得新的java.util.Formatter类更强大:它能将文本格式化为任何可追加的对象,包括你自己的实现。(练习留给读者:你能否将上面的TextFile类变得既可迭代又可追加么?)。

  java.lang.Readable接口和Appendable相反:一个可读对象可以将字符传输给给定的CharBuffer。java.io.Reader和它的全部子类都是可读的(当然了),CharBuffer本身也一样。就像Appendable是为了java.util.Formatter的利益而创造,Readable是为了java.util.Scanner的利益而创造。(Java5.0增加了Scanner,连同Formatter。这是Java对C的scanf()函数的适应,但是它(Scanner)不像Formatter之对应于printf()的关系那样密切。)

  我想讨论的最后两个能力接口是java.io.Closeable和java.io.Flushable。如它们的名字暗示的,它们趋向于被任何类实现,通过一个close()或者flush()方法。Closeable被所有的输入和输出流类,RandomAccessFile和Formatter实现。Flushable被输出流类和Formatter实现。这些接口也是为了Formatter类的利益而定义。注意,Appendable对象(像StringBuilder)不总是可关闭或者可冲刷(flushable)。通过将可关闭性和可冲刷性分解出来成为这些接口,Formatter的close()和flush()方法能够决定它们操作的Appendable对象是否需要被关闭或被冲刷。(Java5.0还增加了第六个能力接口,并且它也是有关Formatter类的。那些想要控制它们的实例怎样被格式化的类可以实现java.util.Formattable接口。然而这个接口的API是难用的,我不想谈论它。)

  @Override

  毫无疑问,你已经听说过能用元数据标注Java5.0的类型和方法。但是你可能不熟悉增加到java.lang的标准标注类型。我喜欢的第四个特性就是java.lang.Override标注。当你写一个方法准备覆盖另一个的方法时,用@Override来标注它,这样编译器会进行检查来确保你确实,实际上,覆盖了你想覆盖的方法。

  如果你拼写错了方法名字或者弄错了方法参数,那么你实际上并没有覆盖那个你认为你覆盖了的方法。这样就造成了一个如果不用@Override很难捕捉的臭虫。我所以知道是因为我的关于Java1.4的新API特性的文章就讲到了这个臭虫,并且这个错误至少有一年一直没被检测到(至少没有被报告)。在那篇文章中,你可以在第一页结尾看到我犯的错误。那篇文章现在包含一个链接到我的博客入口,在那里我改正了这个臭虫并且在代码中增加了@Override声明。

  MatchResult

  我喜欢的Java5.0的最后一个特性是java.util.regex.MatchResult。对于用于正则表达式的模式/匹配API我从来没有真正非常满意。Java5.0增加的MatchResult在让我大大地更加满意。当使用一个不太平凡的模式(Pattern),每次调用匹配者(Matcher)的find()方法会生成许多状态:开始位置,结束位置,匹配的文本,同时还有模式的开始,结束,每个子表达式的文本。在Java5.0以前,你只能从Matcher获取它们,通过在调用find()后再调用start(),end(),还有group(),如果需要的话。

  然而,到了Java5.0,你可以只调用toMatchResult()来获取MatchResult对象再获取全部的状态,MatchResult对象可以保存并且可以以后再检查。MatchResult像Matcher一样有start(),end(),以及group()方法,并且,实际上,Matcher现在实现了MatchResult。

  这里是一个有用的返回MatchResult的方法:

public static List<MatchResult> findAll(Pattern pattern,
               CharSequence text)  {
    List<MatchResult> results =
        new ArrayList<MatchResult>();
    Matcher m = pattern.matcher(text);
    while(m.find()) results.add(m.toMatchResult());
    return results;
}

  还有使用这个方法的代码:

List<MatchResult> results = findAll(pattern, text);
for(MatchResult r : results) {
    System.out.printf("Found '%s' at (%d,%d)%n",
            r.group(), r.start(), r.end());
}

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

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

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