之前写了一篇java 8新特性,相信目前很多人还是使用着java 8,那到底java 11值不值得升级呢,结合之前写的java 8与java 11的性能对比,你可以看完这篇java 11的新特性,再考虑要不要升级到java 11。
局部变量类型推断
java 10新出的特性,局部变量类型推断,使用的是var
关键字,只能在方法体内使用。
在java 10之前,我们的代码需要这么写:
1 | String text = "Hello Java 9"; |
在java 10后,可以使用var
来代替String
:
1 | var text = "Hello Java 10"; |
这种用法只能使用在局部变量上,即方法体内,不能用在成员变量上:
1 | public class VarTest { |
var
说到底其实就是java的语法糖,是靠编译器推断var
的类型并转换回去的,并没有改变java静态语言的本质,如:
1 | var text = "Hello Java 11"; |
想通这一点之后,就可以将var
看成只是简化我们代码书写优点,所以使用final
关键字,也是可以防止var
变量改变的:
1 | final var text = "Banana"; |
确定了var
是语法糖后,对于编译器推断不出来场景,是用不了var
的:
1 | //下面四种都会编译错误 |
var
对于简化我们的书写还是很有帮助的,对于很长的变量如Map<String, List<Integer>>
:
1 | var myList = new ArrayList<Map<String, List<Integer>>>(); |
Java 11后,可以将var
使用在lambda表达式的参数中:
1 | Predicate<String> predicate = (var a) -> true; |
相信写惯静态语言的程序猿,看动态语言其实是很费劲的,因为不知道这个变量到底是什么类型的,对于
var
也是一样,好在IDEA可以通过CMD/CTRL指定var
可以提示变量类型。
HTTP Client
之前的网络请求,我们一般都是使用Apache的Httpclient
工具包,Java 9增加了HttpClient
,并在java 11可以在java.net
中正式使用。
新的HttpClient
可以使用同步或异步的方式请求,并可以使用BodyHandlers
来解析响应体,如同步的写法:
1 | var request = HttpRequest.newBuilder() |
异步的写法:
1 | var request = HttpRequest.newBuilder() |
可以使用BodyPublishers
来发送请求内容,类型可以是字符串、字节数组、文件、输入流等:
1 | var request = HttpRequest.newBuilder() |
如果服务端的身份验证是HTTP协议的授权认证,那么HttpClient
也提供了对应的方法:
1 | var request = HttpRequest.newBuilder() |
Collections
java 11里面的集合如List
、Set
、Map
都提供了新的创建方法,List.of
可以创建新的不可变集合,List.copyOf
可以通过拷贝list
来创建新的不可变的集合,如:
1 | var list = List.of("A", "B", "C"); |
1 | var list = new ArrayList<String>(); |
通过of
方法创建不可变map:
1 | var map = Map.of("A", 1, "B", 2); |
java 11的不可变集合还是以前的那套不可变实现,熟悉java不可变集合的读者都知道,java原生的不可变集合并非真不可变,只是在原集合上套了一个门面。如:A为可变集合,B为通过A构建的不可变集合,如果只是操作B,那是没问题的,但是操作A就有问题了,A添加了一个元素,B也会添加,因为B只是套在A上的门面。
不过java 11的
of
和copyOf
方法保证了A不会被操作到,所以问题不大。
Streams
在java 8新特性里面笔者已经介绍了一些Streams
的方法及用法,也在java 8 stream底层原理里面讲解了它的技术原理,不在重复。在java 11中,streams
增加了三个新的方法,Stream.ofNullable
类似于Optional
可接受一个可能空的实例来构建流:
1 | Stream.ofNullable(null) |
还有dropWhile
and takeWhile
两个方法,不同于filter
方法作用于所有的元素,这两个方法都是遇到第一个false则不在执行while循环:
1 | Stream.of(1, 2, 3, 2, 1) |
Optionals
optional
增加了转换为stream
的方法:
1 | Optional.of("foo").stream().count(); // 1 |
Strings
字符串增加了一些字符操作方法:
1 | " ".isBlank(); // true |
InputStreams
InputStream
增加了一个非常好用的方法,可以直接传递数据导OutputStream
:
1 | var classLoader = ClassLoader.getSystemClassLoader(); |
JVM 特性
java 11除了上面那些语言上的API特性,还增加了一些JVM的新特性,可以直接查看官网:
- Flow API for reactive programming
- Java Module System
- Application Class Data Sharing
- Dynamic Class-File Constants
- Java REPL (JShell)
- Flight Recorder
- Unicode 10
- G1: Full Parallel Garbage Collector
- ZGC: Scalable Low-Latency Garbage Collector
- Epsilon: No-Op Garbage Collector
- Deprecate the Nashorn JavaScript Engine