Java 11 变更
开发相关的部分
相关术语 JEP: JDK Enhancement Proposals, JDK 改善提案 JLS: Java Language Specification, Java 语言规范相关资源 Java11 语言规范(JLS)PDF
JEP 323 Lambda 表达式的本地变量支持
在 JDK 10 中引入了一种本地变量类型(JEP 286),从此你可以不必显式写出局部变量的类型,可以直接用 var
。JEP 323 将这种语法扩展到了 Lambda 表达式中。下面是例子:
会有人说,原来的 Lambda 表达式已经能不写类型名了,像这样:
那为什么还要添加对 var 的支持呢。在某些特殊情况下,如果你想给 Lambda 表达式的参数加标注(annotation)的话,就必须要写类型名了,这时候就可以这样简化:
JLS 相关页码
- P24:对 var 标识符的描述
- P627~630:Lambda 表达式参数
- P636:Lambda 表达式的运行时表现
- P746:Lambda 表达式
JEP 330 直接运行单文件源文件
对于初学者而言,Java 的一整套编译 - 运行流程太复杂了,容易造成从入门到放弃的情况,在 Java 11 中,你不需要自己编译单文件 Java 程序了:
Java 启动器会识别出这是一个源文件,然后就会自动将这个源文件编译再运行。
在文件名后的参数都会被当作 Java 程序启动时的参数,文件名前的参数会被当作 Java 启动器的参数。与编译器相关的参数也会被传给 Java 编译器(如 classpath)。例如
等价于
该提案还提供了 ‘shebang’ 支持,为了减少命令行的输入,在文件的第一行可以这么写:
注意必须要用 --source
来指定使用的 Java 语言版本。
JEP 321 标准 HTTP 客户端
JDK9 引入的一套 HTTP 客户端 API 现在已经被加入 Java SE 11 标准了。在 java.net.http
包中引入了新的类和模块。主要的类型有
该 API 可以异步或同步调用。
JEP 320 删除了 Java EE 和 CORBA 模块
六个位于 java.se.ee
下的模块将不再存在于 Java SE 11 标准中,JDK 也不会包含。下面是受影响的模块:
- corba
- transaction
- activation
- xml.bind
- xml.wa
- xml.wa.annotation
这些模块自 JDK9 以来就被标记成过时 @Deprecated
,而且在编译 - 运行时都不会被默认包含。
JDK-8060192 Collection 类新增方法
Collection
接口新增了 toArray(IntFunction)
方法,这个新方法是 toArray(T[])
的重载,这个新方法引入了些许代码不兼容性,在老版本中,coll.toArray(null)
会被视为调用默认的 toArray(T[])
,而现在会导致编译器无法确定是调用 toArray(T[])
还是调用 toArray(IntFunction)
。这只是对源码的不兼容性,现存的二进制文件不受影响。你只能将 null
显式转化为需要的数组类型,比如 toArray((Object[])null)
。需要注意的是根据标准,将 null
作为 toArray
方法的参数会导致 NullPointerException
。
新 APIs
完整 API 更新列表可以在这里看到。
下面会列出一些比较值得关注的新增 / 改动:
java.io.ByteArrayOutputStream
void writeBytes(byte[])
将所有字节全部输出
java.io.FileReader
两个新的构造函数,允许指定文件的字符集。
java.io.FileWriter
四个新的构造函数,允许指定文件的字符集。
java.io.InputStream
io.InputStream nullInputStream()
返回一个没有读取任何数据的InputStream
,详细见 Java doc
java.io.OutputStream
io.OutputStream nullOutputStream()
java.io.Reader
io.Reader nullReader()
java.io.Writer
- io.Writer nullWriter()
java.lang.Character
String toString(int)
这是一个已有函数的重载,返回的是一个 int 型,表示一个 Unicode 的码点。
java.lang.CharSequence
int compare(CharSequence, CharSequence)
比较两个 CharSequence。
java.lang.Runtimejava.lang.System
runFinalizersOnExit()
在这两个类中都被删除了。
java.lang.String
boolean isBlank()
如果字符串为空或者只有空格返回true
Stream lines()
以行尾分隔符为界,返回一个流String repeat(int)
将原字符串的重复几次后返回String strip()
将原字符串的所有空格删除并返回String stripLeading()
将原字符串领头的空格删除并返回String stripTrailing()
将原字符串末尾的空格删除并返回
strip()
和 trim()
的区别在于他们对空格的定义不同,strip()
的定义可以参照 Character.isWhitespace(int)
java.lang.StringBufferjava.lang.StringBuilder
这两个类都新增了一个 compareTo()
方法,和 CharSequence
类似。
java.lang.Thread
destroy()
和 stop(Throwable)
已被删除。
java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer
这些类都新增了 mismatch()
方法。
这些 API 看的头疼,改天再继续写吧
开发无关的部分
JEP 181 嵌套类访问控制
Java 支持嵌套类,要使代码能够正确的运行,编译器需要一些 trick。比如:
编译器会修改成下面的样子来编译:
然而从逻辑上来说,内部类应该是外部类的一部分,但它却被编译成了一个单独的类。这么一来就需要编译器生成一个函数来使内部类获得外部类成员的访问权限。
该提案引入了嵌套的一组概念:两个处于同一个嵌套区域(nest)中的成员称为”nestmate”。在上面的例子里就是 Outer
和 Inner
。在类文件中有两个新的属性:NestHost
和 NestMembers
。这个新特性为 java.lang.Class
引入了三个新方法:
- Class getNestHost()
- Class[] getNestMembers()
- boolean isNestmateOf(Class)
新特性同样更新了 Java 虚拟机规范:Java Virtual Machine Specification (JVMS), section 5.4.4, Access Control.
相关信息:Java Nestmate 稳步推进
JEP 309 动态类文件常量
这个提案将引入一种动态常量,这个常量的值不是在编译时确定的,而是在类加载时载入函数动态确定的。
JEP 324 Curve25519 和 Curve448
现有的 elliptic-curve Diffie-Hellman
被 Curve25519
和 Curve448
取代。
JEP 327 Unicode 10
(就是支持 Unicode 10 了,有什么好说的)
JEP 329 ChaCha20 和 Poly1305 加密算法
就是支持了,下一个
JEP 332 TLS 1.3 !!!
为什么我这么激动,可能是因为我们的 Steam 组叫做 TLSv1.3 吧。
JEP 335 废除 Nashorn 脚本引擎
Nashorn 作为一个高性能的 Javascript 引擎在 JDK8 中引入。因为相关 API 的原因将被移除,目前提议使用新引擎 GraalVM。