1.8 接口中的静态方法

1.8 接口中的静态方法

在Java 8 中,你可以为接口添加静态方法。从技术角度来说,这是完全合法的。只是它看起来违反了接口作为一个抽象定义的理念。

至今为止,我们经常在相互一起使用的类中使用静态方法。你可以在标准库中找到像Collection/Collections 或者Path/Paths 这样成对的接口和类。

以Paths 类为例,它只有一些工厂方法。你可以通过一组字符串来构造一个路径,例如Paths.get("jdk1.8.0", "jre", "bin")。在Java 8 中,Path 接口中添加了这样一个方法:
 

  1. public interface Path {  
  2. public static Path get(String first, String... more) {  
  3. return FileSystems.getDefault().getPath(first, more);  
  4. }  
  5. ...  

这样Paths 类就再没有存在的必要了。

当你查看Collections 类时,你会发现两种方法,一种如下所示:
 

  1. public static void shuffle(List<?> list) 

这类方法可以作为List 接口中的一个默认方法:
 

  1. public default void shuffle() 

然后你只需要在任何list 对象上调用list.shuffle()。

但是这样无法适用于静态的工厂方法,因为你没有可用的对象来调用该方法。因此,Java 8 中引入了静态接口方法。例如:
 

  1. public static <T> List<T> nCopies(int n, T o)  
  2. // 构造含有n 个o 类型实例的列表 

它可以作为List 接口的一个静态方法。这样你就可以调用List.nCopies(10,"Fred"),而不是Collections.nCopies(10, "Fred"),就能够更清楚地表示返回的结果是一个List 对象。

虽然Java 的集合类不太可能像这样进行重构,但是当你实现自己的库时,不必再为工具方法提供一个辅助的类了。

在Java 8 中,很多接口中已经添加了静态方法。例如,Comparator 接口提供了一个很实用的比较方法,它接收一个“键提取”函数,并产生一个用来比较所提取出的键的比较器。例如, 要根据名称对Person 对象进行比较, 你可以使用函数Comparator.comparing(Person::get name)。

在本章中,我们曾经使用lambda 表达式(first, second) -> Integer.compare(first.length(), second.length())对字符串的长度进行比较。但是如果使用静态的比较方法, 代码会变得更加简洁, 例如Comparator.comparing(String::length)。这个例子很适合作为本章的结尾,因为它充分展示了函数的强大功能。compare 方法将一个函数(键提取)转变为了一个更复杂的函数(基于键的比较器)。我们将会在第3 章中更详细地介绍这种“高阶函数”。

posted @ 2016-12-22 14:38  叶枫声  阅读(901)  评论(0编辑  收藏  举报