Java8-11的新特性
Java8
Lambda & Functional Interface
1 |
|
误区:
- 认为的:通过匿名函数生成Runnable对象,传递给Thread
- 事实上:内部优化直接调用了匿名函数(invokedynamic指令)
方法引用::操作符
1 | public class MethodReference { |
Stream
一个Monad。 函数式、流计算重磅炸弹,见之前讲流和Monad部分 。
Optional
一个Monad。 流计算必备工具,减少空值检查。另一个还没有支持,但比较重要的Monad是Try。这个在实现AOP框架的程序中,我们已经使用到了。见之前讲流和Monad部分
接口的方法(static, default, private)
- static(java 8)
- default(java 8)
- private(java 9)
1 | public interface Stream<T> extends BaseStream<T, Stream<T>> { |
Java 8 Nashorn JavaScript
在Java8中增加,在Java11中标记为Deprecated, 在Java15中移出的新特性。支持javascriptES5语法。
1 | public void test_engine() throws ScriptException { |
脚本这么多专门选JS没有优势。
本地化日期处理升级
提供了Local和Zoned两种处理日期的方式,在新的API中不再允许mutable的操作(非线程安全);另外对时区采取更好的处理方法:如果用户的系统不考虑国际化,那么就用Local的日期,如果考虑国际化,可以构造带时区的DateTime。
1 |
|
内置了Base64工具
tips: 对0~255之间的字符,Base64编码是以4个可见字符去描述3个字符。会增加数据的体积,但是因为所有字符都可以读,用Base64编码描述的字符串,在URL、XML中都不会被转义。
Base64.Decoder和Base64.Encoder类。
Java9新特性
模块系统
因为和底层原理知识结合紧密,在ClassLoader部分介绍。
交互式编程环境(JShell)

除了上图中的能力,也提供API,可以动态的eval程序。
新的HTTP 2.0 Clinet
主要针对旧Client,提供Buidler,方便用户设置header和参数。
另外支持HTTP2.0,HTTP2.0兼容HTTP1.1的能力,主要是从性能角度进行了调优。理解HTTP2.0主要是这几个特性:
- 多个HTTP 请求/返回在一个TCP请求上多路复用(客户端要负责实现多路复用)
- 头部压缩算法(客户端要负责解压)
- Server Push:服务器可能会给客户端额外的文件(浏览器要负责识别,并缓存这些文件,客户端不一定要实现)
1 | HttpClient httpClient |
改进了Javadoc
大家平时读的很多Java的文档(特别是官方的文档),就是用Javadoc生成的。 所以这也是Java文档——比较难读的原因之一。 写程序的人注释往往是为了让内部人员读懂,而文档是面向外部人员。
例如:
1 | javadoc -d foo -html5 MyHelloWorld.java |
可以生成符合HTML5标准的网页。
支持multirelease jar包
项目目录结构可以这样安排,不同的版本的程序在不同的目录下。
1 | |-java |
然后可以通过javac** **编译成不同版本的class文件:
1 | javac --release 9 java8/hello/xxx.java |
最后用jar** 可以产生不同版本的**jar** **包:
1 | jar -c -f xxx.jar -C java8 . --release 9 -C java9. |
这样xxx.jar** **中会同时有java8和java9的程序。
1 | java -cp test.jar hello // 不同java版本访问不同的类 |
这个功能的意义是什么?
Java升级太快了,多版本同时发布,让程序的提供者可以兼容不同用户的需求。
集合的工厂方法
1 | var set = Set.of("Apple", "Google"); |
增加ProcessHandler
增加了一个ProcessHandler用于查看某个特定进程的信息:启动时间、关联参数等等。目前是加强对进程的支持。
1 | ProcessBuilder builder = new ProcessBuilder("ls -l"); |
Stream API增加了方法
为了方便操作,提供了更多的Stream API。
- takeWhile
字面意思:take while x != 7 is hold , 中文意思:在x != 7的时候,拿,否则停下来
1 | Stream.of(2,1,3,7,4,6,8,0).takeWhile(x -> x != 7) |
- dropWhile
字面意思: drop while x!=7 is hold, 中文意思:在x!=7的时候,丢弃,否则停下来
1 | Stream.of(2,1,3,7,4,6,8,0).dropWhile(x -> x!=7) |
- iterate
1 | Stream.iterate( |
另外一个例子:
1 | jshell> Stream.iterate("i", x -> x.length() < 20, x->x+"i").collect(Collectors.toList()); |
- ofNullable
1 | Stream.ofNullable(null); // Stream.empty() |
<>钻石操作符语法优化
允许匿名类使用钻石操作符。
1 | Iterable<Integer> it = new Iterable<>() { |
CompletableFuture改进
CompletableFuture是java异步计算能力的核心,代表一个需要在未来被计算出来的的值。
在 Java9中针对已有能力,对CompletableFuture进行了提升。
增加completeOnTimeout方法
1 |
|
增加直接成功/失败的future工厂方法
1 |
|
更多参考并发部分有一节对Future的专项突破课程
try-with-resources的改进
Java中的一部分资源对象会继承于Closeable接口,这就可以使用try-with-resources** **能力。例如:
1 | public abstract class InputStream implements Closeable { |
如果要使用的话:
1 |
|
上面直接对某个实现了Closeable的对象进行try,并且主动触发close能力, 是Java9的一个优化。
Java 10
局部变量类型推断
1 | var list = new LinkedList<Integer>(); |
JDK代码仓库整理
所有JDK代码不再使用8个仓库存储:root、corba、hotspot、jaxp、jaxws、jdk、langtools、nashorn。
统一成为1个仓库。
主要是解决原子提交的问题:1个功能可能需要更新多个代码仓库。
G1增加并行能力
在mark-sweep-compact的GC算法上,再增加并行 能力。
见JVM GC部分
优化:应用程序数据共享(Application Data Sharing)
ADS: 允许多个JVM实例共享共同用到的类,这些类以共享内存的形式存在。这样对于运行了多个JVM的机器,可以节省内存空间以及类的加载速度。
计划移除JNI头生成工具
JNI(Java Native Interface)是Java程序和Native(C, C++)程序沟通的接口。 一个Java类,如果要Native调用,通常是在Android开发当中,需要生成一个C/C++的头文件。之前可以用javah来生成,现在用javah工具生成的时候,会有一行warning。
以后JNI的能力会被Panama项目替代,一个专门为非java语言提供接口的库。
增加实验性的Graal编译器
可以配置参数开启:
1 | -XX:+ UnlockExperimentalVMOptions -XX:+ UseJVMCICompiler |
Graal是一款同时支持JIT和AOT的编译器。
- JIT(Just in Time)一边编译一边执行,执行完第一次之后,下一次不需要编译
- AOT(Ahead of Time),类似C/C++那样,先编译成机器码,再执行。 注意,是机器码,越过了JVM的bytecode。
目前还是实验阶段,不建议用作生产。已经发现了不少的Bug,等待进一步的修复。
Java 11
引入NestedMembers概念
嵌套类和它的父亲作为一组NestedMembers,可以互相访问元数据。
1 |
|
增加无操作GC回收器:Epsilon
Epsilon不会进行垃圾回收操作,是的,你没有看错, 它不进行GC。
1 | -XX:+UseEpsilonGC |
Epsilon虽然不GC,但是仍然承担着内存分配的工作。(Java 的 GC也是Java的内存管理工具,更多见GC部分)
有点:
- 对于开发者明确知道不需要GC的程序有助于减少延迟
- 对于性能测试、压力测试场景,可以忽略GC带来的延迟
Lambda优化:允许使用 var定义匿名函数形参
1 | My{} |
优化:增加字符串能处理函数
1 | " ".isBlank(); // true |