Java8的新特性和改进总览(1)

  这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布。

  在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API仍然有可能改变,我会尽我最大的努力保持这份文档跟得到Java 8的改动。

  Java 8的预览版,也就是 “Project Lambda”,现在可以从java.net下载到。

  我使用了IntelliJ的预览版做我的IDE,在我看来他是目前支持java 8特性最好的一个IDE,你可以从这里下载到.

  由于我没有找到Oracle发布的Java 8的官方文档,所以目前Java 8的文档还只有本地版本,等Oracle公开文档的时候,我将会重新链接到官方文档。

  接口改善

  现在接口里已经完全可以定义静态方法了. 举一个比较普遍的例子就是在java类库中, 对于一些接口如Foo, 都会有一个有静态方法的工具类Foos来生成或者配合Foo对象实例来使用. 既然静态方法可以存在于接口当中, 那么大多数情况下 Foos工具类完全可以使用接口中的公共方法来代理 (或者将Foos置成package-private).

  除此之外更重要的就是, Java 8中接口可以定义默认的方法了.举个例子,一个for-each循环的方法就可以加入到java.lang.Iterable中:

  publicdefaultvoidforEach(Consumer<?superT>action){   Objects.requireNonNull(action);for(Tt:this){   action.accept(t);   }   }

  在过去,java类库的接口中添加方法基本上是不可能的. 在接口中添加方法意味着破坏了实现了这个接口的代码. 但是现在, 只要能够提供一个正确明智的默认的方法的实现, java类库的维护者就可以在接口中添加方法.

  Java 8中, 大量的默认方法已经被添加到核心的JDK接口中了. 稍候我会详细介绍它们.

  为什么不能用默认方法来重载equals,hashCode和toString?

  接口不能提供对Object类的任何方法的默认实现。特别是,这意味着从接口里不能提供对equals,hashCode或toString的默认实现。

  这刚看起来挺奇怪的,但考虑到一些接口实际上是在文档里定义他们的equals行为的。List接口就是一个例子了。因此,为什么不允许这样呢?

  Brian Goetz在这个问题上的冗长的回复里给出了4个原因。我这里只说其中一个,因为那个已经足够说服我了:

  它会变得更困难来推导什么时候该调用默认的方法。现在它变得很简单了:如果一个类实现了一个方法,那总是优先于默认的实现的。一旦所有接口的实例都是Object的子类,所有接口实例都已经有对equals/hashCode/toString的非默认实现。因此,一个在接口上这些的默认版本都是没用的,它也不会被编译。

  要看更多的话,看下由Brian Goetz写的解释:对“允许默认方法来重载Object的方法”的回复

  函数式接口

  Java 8 引入的一个核心概念是函数式接口。如果一个接口定义个唯一一个抽象方法,那么这个接口就成为函数式接口。比如,java.lang.Runnable就是一个函数式接口,因为它只顶一个一个抽象方法:

  publicabstractvoidrun();

  留意到“abstract”修饰词在这里是隐含的,因为这个方法缺少方法体。为了表示一个函数式接口,并非想这段代码一样一定需要“abstract”关键字。

  默认方法不是abstract的,所以一个函数式接口里可以定义任意多的默认方法,这取决于你。

  同时,引入了一个新的Annotation:@FunctionalInterface。可以把他它放在一个接口前,表示这个接口是一个函数式接口。加上它的接口不会被编译,除非你设法把它变成一个函数式接口。它有点像@Override,都是声明了一种使用意图,避免你把它用错。

无论何时何地,只要创造就有收获,只有不息的奋进,才能证明生命的存在。

Java8的新特性和改进总览(1)

相关文章:

你感兴趣的文章:

标签云: