设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

新版观察:Java 8的新特性和改进总览

2013-5-2 10:12| 发布者: joejoe0332| 查看: 4492| 评论: 0|原作者: super0555, throwable, 等PM, LinuxQueen, JeromeCui, 乔学士, Sender, 叫我蝴蝶吧|来自: oschina

摘要:   这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布。   在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API仍然有可能改变 ...

泛型接口改进

建议摘要:JEP 101: 通用化目标-Type 接口

这是一个以前不能做到的,对编译器判定泛型能力的努力改进。在以前版本的Java中有许多情形编译器不能给某个方法计算出泛型,当方法处于嵌套的或串联方 法调用这样的上下文的时候,即使有时候对程序员来说它看起来“很明显”。那些情况需要程序员明确的指定一个“类型见证”(type witness)。它是一种通用的特性,但吃惊的是很少有Java程序员知道(我这么说是基于私下的交流并且阅读了一些StackOverflow的问 题)。它看起来像这样:

1// In Java 7: foo(Utility.<Type>bar());
2Utility.<Type>foo().bar();

如果没有类型见证,编译器可能会将<Object>替代为泛型,而且如果需要的是一个更具体的类型,代码将编译失败。

Java 8 极大的改进了这个状况。在更多的案例中,它可以基于上下文计算出更多的特定的泛型类型。
1// In Java 8: foo(Utility.bar());
2Utility.foo().bar();

这项工作仍在发展中,所以我不确定建议中列出的例子有多少能真正包含进Java 8。希望是它们全部。

java.time

包概要: java.time

在Java8中新的 date/timeAPI存在于 java.time包中。如果你熟悉Joda Time,它将很容易掌握。事实上,我认为如此好的设计,以至于从未听说过 Joda Time的人也能很容易的掌握。

几乎在API中的任何东西都是永恒的,包括值类型和格式化 。对于Date域或者处理或处理本地线程日期格式化不必太过担心。

与传统的date/timeAPI的交叉是最小的。有一个清晰的分段:


新API对于像月份和每周的天数,喜欢枚举类型更胜过整形常量。

那么,那是什么呢?包级别的javadocs 对额外类型的做出了非常好的阐述。我将对一些值得注意的部分做一些简短的纲要。

非常有用的值类型:

其他有用的类型:

  • DateTimeFormatter - 将日期类型转换成字符串类型
  • ChronoUnit - 计算出两点之间的时间量,例如ChronoUnit.DAYS.between(t1, t2)
  • TemporalAdjuster - 例如date.with(TemporalAdjuster.firstDayOfMonth())

大多数情况下,新的值类型由JDBC提供支持。有一小部分异常,如ZonedDateTime在SQL中没有对应的(类型)。

集合API附件

实际上接口能够定义默认方法允许了JDK作者加入大量的附件到集合API接口中。默认实现在核心接口里提供,而其他更有效或更好的重载实现被加入到可适用的具体类中。

这里是新方法的列表:

同样, Iterator.remove() 现在有一个默认的, 会抛出异常的实现,使得它稍微容易地去定义不可修改的迭代器。

Collection.stream()和Collection.parallelStream()是流API的主要门户。有其他方法去生成流,但这些在以后会更为长用。

List.sort(Comparator)的附件有点怪异。以前排序一个ArrayList的方法是:

1Collections.sort(list, comparator);

这代码是你在Java7里唯一可选的,非常低效。它会复制list到一个数组里,排序这个数组,然后使用ListIterator来把数组插入到新list的新位置上。

List.sort(比较器)的默认实现仍然会做这个,但是具体的实现类可以自由的优化。例如,ArrayList.sort在ArrayList内部数组上调用了Arrays.sort。CopyOnWriteArrayList做了同样的事情。

从这些新方法中获得的不仅仅是性能。它们也具有更多的令人满意的语义。例如, 对Collections.synchronizedList()排序是一个使用了list.sort的原子操作。你可以使用list.forEach对 它的所有元素进行迭代,使之成为原子操作。

Map.computeIfAbsent使得操作类似多重映射的结构变得容易了:

1// Index strings by length:
2Map<Integer, List<String>> map = new HashMap<>(); for (String s : strings) {
3    map.computeIfAbsent(s.length(),
4                        key -> new ArrayList<String>())
5       .add(s);
6} // Although in this case the stream API may be a better choice:
7 Map<Integer, List<String>> map = strings.stream()
8    .collect(Collectors.groupingBy(String::length));

增加并发API

有太多的链接可以点击,因此参看ConcurrentHashMap javadocs文档以获得更多信息。

  • ConcurrentHashMap.reduce...
  • ConcurrentHashMap.search...
  • ConcurrentHashMap.forEach...
ForkJoinPool.commonPool()是处理所有并行流操作的结构。当你 需要的时候,它是一个好而简单的方式去获得一个 ForkJoinPool/ExecutorService/Executor对象。ConcurrentHashMap<K, V>完全重写。内部看起来它一点不像是Java7版本。从外部来看几乎相同,除了它有大量批量操作方法:多种形式的减少搜索和forEach。
ConcurrentHashMap.newKeySet()提供了一个并发的java.util.Set实现。它基本上是 Collections.newSetFromMap(new ConcurrentHashMap<T, Boolean>())的另一种方式的重写。

StampedLock是一种新型锁的实现,很可能在大多数场景都可以替代ReentrantReadWriteLock。 当作为一个简单的读写锁的时候,它比RRWL的性能要好。它也为“读优化”提供了API,通过它你获得了一个功能有点弱,但代价很小的读操作锁的版本,执 行读操作,然后检查锁是否被一个写操作设定为无效。在Heinz Kabutz汇总的一系列幻灯片中,有更多关于这个类及其性能的细节(在这个系列幻灯片大约一半的地方开始的):"移相器和StampedLock演示"

CompletableFuture<T>是Future接口的一个非常棒的实现,它提供了无数执行(和串接)异步任务的方法。它特别依赖功能性的接口;lambdas是值得增加这个类的一个重要原因。如果你正在使用Guava的 Future工具,例如Futures, ListenableFuture, 和 SettableFuture,那么你可能会希望校验CompletableFuture能否作为潜在的替代选择。

IO/NIO API的新增内容

简单的说,这些API用于从文件和InputStreams获取java.util.stream.Stream对象。不过它们与直接从常规的collection得到的流有些不同,它们引入了两个概念:

  • UncheckedIOException - 当有IO错误时抛出这个异常,不过由于Iterator/Stream的签名中不允许有IOException,所以它只能借助于unchecked异常。
  • CloseableStream - 可以(并且应该)定义在 try-with-resources 语句里面的流。

酷毙

雷人

鲜花
1

鸡蛋

漂亮

刚表态过的朋友 (1 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部