Java5到Java7的新特性见这里:https://www.jianshu.com/p/a051a2f0c3ab
Java8新特性
- lamda表达式(
重磅
) - 集合的stream操作
- 提升HashMaps的性能
- Date-Time Package
- java.lang and java.util Packages
- Concurrency
lamda表达式(重磅
)
方法引用
/**
* 静态方法引用:ClassName::methodName
* 实例上的实例方法引用:instanceReference::methodName
* 超类上的实例方法引用:super::methodName
* 类型上的实例方法引用:ClassName::methodName
* 构造方法引用:Class::new
* 数组构造方法引用:TypeName[]::new
* Created by codecraft on 2016-02-05.
*/
public class MethodReference {
@Test
public void methodRef(){
SampleData.getThreeArtists().stream()
.map(Artist::getName)
.forEach(System.out::println);
}
@Test
public void constructorRef(){
ArtistFactory af = Artist::new;
Artist a = af.create("codecraft","china");
System.out.println(a);
}
}
集合的stream操作
/**
* 主要接口
* 1,predicate
* 2,Unary/BinaryOperator:传入参数和返回值必然是同一种数据类型
* 3,Int/Double/LongFunction/BiFunction:函数接口并不要求传入参数和返回值之间的数据类型必须一样
* 4,Int/Long/DoubleConsumer/BiConsumer:消费数据
* 5,Int/Long/DoubleSupplier:生产数据
*
* 主要方法:
* 1,filter
* 2,map
* 3,reduce
* 4,collect
* 5,peek
* -Djdk.internal.lambda.dumpProxyClasses
* Created by codecraft on 2016-02-05.
*/
public class LamdaDemo {
int[] arr = {4,12,1,3,5,7,9};
@Test
public void filter(){
Arrays.stream(arr).filter((x) -> x%2 !=0).forEach(System.out::println);
}
@Test
public void map(){
Arrays.stream(arr).map((x) -> x * x).forEach(System.out::println);
}
@Test
public void reduce(){
Arrays.stream(arr).reduce((x,y) -> x+y).ifPresent(System.out::println);
System.out.println(Arrays.stream(arr).reduce(-10, (x, y) -> x + y));
}
@Test
public void collect(){
List list = Arrays.stream(arr).collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
System.out.println(list);
Set set = list.stream().collect(Collectors.toSet());
System.out.println(set);
Map map = SampleData.getThreeArtists().stream()
.collect(Collectors.toMap(a -> a.getName(),a -> a));
System.out.println(map);
}
@Test
public void peek(){
long count = Arrays.stream(arr).filter(x -> x > 2).peek(System.out::println).count();
System.out.println(count);
}
@Test
public void average(){
Arrays.stream(arr).average().ifPresent(System.out::println);
}
@Test
public void sum(){
System.out.println(Arrays.stream(arr).sum());
}
@Test
public void max(){
Arrays.stream(arr).max().ifPresent(System.out::println);
}
@Test
public void min(){
Arrays.stream(arr).min().ifPresent(System.out::println);
}
@Test
public void sorted(){
Comparator asc = (x,y) -> x.getName().compareTo(y.getName());
SampleData.getThreeArtists().stream().sorted(asc).forEach(System.out::println);
SampleData.getThreeArtists().stream().sorted(asc.reversed()).forEach(System.out::println);
SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName)).forEach(System.out::println);
SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).reversed()).forEach(System.out::println);
SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).thenComparing(Artist::getNationality)).forEach(System.out::println);
}
@Test
public void groupBy(){
Map> rs = SampleData.getThreeArtists().stream().collect(Collectors.groupingBy(Artist::getNationality));
System.out.println(rs);
}
@Test
public void join(){
String joinedNames = SampleData.getThreeArtists().stream().map(Artist::getName).collect(Collectors.joining(","));
System.out.println(joinedNames);
joinedNames.chars().mapToObj(c -> (char) Character.toUpperCase(c)).forEach(System.out::println);
}
@Test
public void flatMap(){
Set rs = SampleData.getThreeArtists().stream().flatMap(a -> a.getMembers()).collect(Collectors.toSet());
rs.stream().forEach(System.out::println);
}
@Test
public void arrStream(){
Arrays.stream(arr).forEach(System.out::println);
}
@Test
public void then(){
// IntConsumer out = System.out::println;
// IntConsumer err = System.err::println;
IntConsumer out = (x) -> System.out.println("out consume:"+x);
IntConsumer err = (x) -> System.err.println("err consume:"+x);
// Arrays.stream(arr).forEach(out.andThen(err));
Arrays.stream(arr).forEach(err.andThen(out));
}
@Test
public void foreach(){
List numbers = Arrays.asList(1,2,3,4,5,6);
numbers.forEach(System.out::println);
}
@Test
public void visitOuterVar(){
final int num = 2;
Function fun = (from) -> from * num;
System.out.println(fun.apply(3));
}
}
提升HashMaps的性能
当hash冲突时,以前都是用链表存储,在java8里头,当节点个数>=TREEIFY_THRESHOLD - 1时,HashMap将采用红黑树存储,这样最坏的情况下即所有的key都Hash冲突,采用链表的话查找时间为O(n),而采用红黑树为O(logn)。
Date-Time Package
Java 8新增了LocalDate和LocalTime接口,一方面把月份和星期都改成了enum防止出错,另一方面把LocalDate和LocalTime变成不可变类型,这样就线程安全了。
@Test
public void today(){
LocalDate today = LocalDate.now();
System.out.println(today);
}
@Test
public void parseString(){
// 严格按照ISO yyyy-MM-dd验证,02写成2都不行,当然也有一个重载方法允许自己定义格式
LocalDate date = LocalDate.parse("2016-02-05");
System.out.println(date);
}
@Test
public void calculate(){
LocalDate today = LocalDate.now();
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(firstDayOfThisMonth);
// 取本月第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2);
System.out.println(secondDayOfThisMonth);
// 取本月最后一天,再也不用计算是28,29,30还是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfThisMonth);
// 取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
System.out.println(nextDay);
// 取2015年1月第一个周一,这个计算用Calendar要死掉很多脑细胞:
LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
System.out.println(firstMondayOf2015);
}
@Test
public void getTime(){
LocalTime now = LocalTime.now();
System.out.println(now);
}
@Test
public void getTimeWithoutMillis(){
LocalTime now = LocalTime.now().withNano(0);
System.out.println(now);
}
@Test
public void parseTime(){
LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00
System.out.println(zero);
LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00
System.out.println(mid);
}
java.lang and java.util Packages
比如数组的并行排序
public class UtilDemo {
int[] data = {4,12,1,3,5,7,9};
@Test
public void parallelSort(){
Arrays.parallelSort(data);
System.out.println(Arrays.toString(data));
}
@Test
public void testCollectPrallel() {
//[4, 16, 17, 20, 25, 32, 41]
Arrays.parallelPrefix(data, Integer::sum);
System.out.println(Arrays.toString(data));
}
}
比如文件遍历
@Test
public void list() throws IOException {
Files.list(Paths.get(".")).filter(Files::isDirectory).forEach(System.out::println);
}
@Test
public void walk() throws IOException {
Files.walk(Paths.get("."), FileVisitOption.FOLLOW_LINKS).forEach(System.out::println);
}
Concurrency
- StampedLock
public class BankAccountWithStampedLock {
private final StampedLock lock = new StampedLock();
private double balance;
public void deposit(double amount) {
long stamp = lock.writeLock();
try {
balance = balance + amount;
} finally {
lock.unlockWrite(stamp);
}
}
public double getBalance() {
long stamp = lock.readLock();
try {
return balance;
} finally {
lock.unlockRead(stamp);
}
}
}
测试
@Test
public void bench() throws InterruptedException {
BankAccountWithStampedLock account = new BankAccountWithStampedLock();
ExecutorService pool = Executors.newCachedThreadPool();
List> callables = IntStream.range(1,5)
.mapToObj(x -> (Callable) () -> {
// if (x % 2 == 0) {
// return account.getBalance();
// } else {
// account.deposit(x);
// return 0d;
// }
account.deposit(x);
return 0d;
})
.collect(Collectors.toList());
pool.invokeAll(callables).forEach(x -> {
try {
System.out.println(x.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
});
pool.shutdown();
System.out.println(account.getBalance());
}
- ConcurrentHashMap的stream支持
参考
- What's New in JDK 8
- 如何在Java 8中愉快地处理日期和时间
Java9新特性
9版本是过渡版本
Java9 开始,Oracle公司转变方式,每6个月发布一次新版本,Java将更加有活力,其他语言的语法糖或编译器已经很先进、方便,Java不能不开始变革,Oracle希望6个月一个次版本发布,逐步将这个庞大的生态改变,目标是再一次引领时代的未来,来让我们看下9到12版本的变迁吧。
- Java原生态支持模块化,精简jdk
- G1成为默认垃圾回收装置
- Java原生封装方便的操作http协议的工具
- Jshell,Java开始原生支持交互脚本,或者简称命令行
- 集合框架进一步优化
- 提供类的工厂化构建方法
- 支持docker
完整的特性详见JDK 9 features,这里列几个相对重要的:
模块系统JPMS(重磅
)
相关的规范及JEP:
- Java Platform Module System (JSR 376)
- JEP 261: Module System
- JEP 200: The Modular JDK
- JEP 201: Modular Source Code
- JEP 282: jlink: The Java Linker
- JEP 220: Modular Run-Time Images
- JEP 260: Encapsulate Most Internal APIs
相关解读
- java9系列(三)模块系统精要
- java9 opens与exports的区别
- java9迁移注意事项
- java9 module相关选项解析
G1成为默认垃圾回收器
相关JEP:
- JEP 248: Make G1 the Default Garbage Collector
- JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector
- JEP 278: Additional Tests for Humongous Objects in G1
相关解读
- java9系列(九)Make G1 the Default Garbage Collector
Unified JVM/GC Logging
相关JEP:
- JEP 158: Unified JVM Logging
- JEP 264: Platform Logging API and Service
- JEP 271: Unified GC Logging
相关解读
- java9 gc log参数迁移
HTTP/2 Client(Incubator)
支持HTTP2,同时改进httpclient的api,支持异步模式。
相关JEP
- JEP 110: HTTP/2 Client (Incubator)
相关解读
- java9系列(六)HTTP/2 Client (Incubator)
jshell: The Java Shell (Read-Eval-Print Loop)
相关JEP
- JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
相关解读
- java9系列(一)安装及jshell使用
Convenience Factory Methods for Collections
相关JEP
- JEP 269: Convenience Factory Methods for Collections
以前大多使用Guava类库集合类的工厂,比如
Lists.newArrayList(1,2,3,4,5);
Sets.newHashSet(1,2,3,4,5);
Maps.newHashMap();
注意,上面这种返回的集合是mutable的
现在java9可以直接利用jdk内置的集合工厂,比如
List.of(1,2,3,4,5);
Set.of(1,2,3,4,5);
Map.of("key1","value1","key2","value2","key3","value3");
注意,jdk9上面这种集合工厂返回的是immutable的
Process API Updates
相关JEP
- JEP 102: Process API Updates
相关解读
- java9系列(四)Process API更新
Stack-Walking API
相关JEP
- JEP 259: Stack-Walking API
相关解读
- java9系列(五)Stack-Walking API
Variable Handles
相关JEP
- JEP 193: Variable Handles
相关解读
- java9系列(七)Variable Handles
docker方面支持
- Java SE support for Docker CPU and memory limits
- Docker CPU limits
- Experimental support for Docker memory limits
- Docker memory limits
其他
-
JEP 238: Multi-Release JAR Files
- java9系列(八)Multi-Release JAR Files
JEP 266: More Concurrency Updates
JEP 274: Enhanced Method Handles
JEP 295: Ahead-of-Time Compilation
小结
java9大刀阔斧,重磅引入了模块化系统,自身jdk的类库也首当其冲模块化。新引入的jlink可以精简化jdk的大小,外加Alpine Linux的docker镜像,可以大大减少java应用的docker镜像大小,同时也支持了Docker的cpu和memory限制(Java SE 8u131及以上版本开始支持
),非常值得使用。
doc
- JDK 9 features
- Java 9 新特性概述
- java9系列(一)安装及jshell使用
- java9系列(二)docker运行java9
- java9系列(三)模块系统精要
- java9系列(四)Process API更新
- java9系列(五)Stack-Walking API
- java9系列(六)HTTP/2 Client (Incubator)
- java9系列(七)Variable Handles
- java9系列(八)Multi-Release JAR Files
- java9系列(九)Make G1 the Default Garbage Collector
- java9 opens与exports的区别
- java9迁移注意事项
- java9 gc log参数迁移
- java9 module相关选项解析
- 使用maven构建java9 service实例
- 使用示例带你提前了解 Java 9 中的新特性
Java10新特性
10是过渡版本
特性列表
- 286: Local-Variable Type Inference(
重磅
)
相关解读: java10系列(二)Local-Variable Type Inference
- 296: Consolidate the JDK Forest into a Single Repository
- 304: Garbage-Collector Interface
- 307: Parallel Full GC for G1
- 310: Application Class-Data Sharing
- 312: Thread-Local Handshakes
- 313: Remove the Native-Header Generation Tool (javah)
- 314: Additional Unicode Language-Tag Extensions
- 316: Heap Allocation on Alternative Memory Devices
- 317: Experimental Java-Based JIT Compiler(
重磅
)
相关解读: Java10来了,来看看它一同发布的全新JIT编译器
- 319: Root Certificates
相关解读: OpenJDK 10 Now Includes Root CA Certificates
- 322: Time-Based Release Versioning
相关解读: java10系列(一)Time-Based Release Versioning
细项解读
上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见What's New in JDK 10 - New Features and Enhancements,这里举几个例子。
Optional.orElseThrow()
/Library/Java/JavaVirtualMachines/jdk-10.jdk/Contents/Home/lib/src.zip!/java.base/java/util/Optional.java
- 源码
/**
* If a value is present, returns the value, otherwise throws
* {@code NoSuchElementException}.
*
* @return the non-{@code null} value described by this {@code Optional}
* @throws NoSuchElementException if no value is present
* @since 10
*/
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
- 实例
@Test
public void testOrElseThrow(){
var data = List.of("a","b","c");
Optional optional = data.stream()
.filter(s -> s.startsWith("z"))
.findAny();
String res = optional.orElseThrow();
System.out.println(res);
}
新增了orElseThrow与get相对应
输出
java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.orElseThrow(Optional.java:371)
at com.example.FeatureTest.testOrElseThrow(FeatureTest.java:19)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
APIs for Creating Unmodifiable Collections
java9新增的of工厂方法的接口参数是一个个元素,java10新增List.copyOf, Set.copyOf,及Map.copyOf用来从已有集合创建ImmutableCollections
- List.copyOf源码
/**
* Returns an unmodifiable List containing the elements of
* the given Collection, in its iteration order. The given Collection must not be null,
* and it must not contain any null elements. If the given Collection is subsequently
* modified, the returned List will not reflect such modifications.
*
* @implNote
* If the given Collection is an unmodifiable List,
* calling copyOf will generally not create a copy.
*
* @param the {@code List}'s element type
* @param coll a {@code Collection} from which elements are drawn, must be non-null
* @return a {@code List} containing the elements of the given {@code Collection}
* @throws NullPointerException if coll is null, or if it contains any nulls
* @since 10
*/
@SuppressWarnings("unchecked")
static List copyOf(Collection extends E> coll) {
if (coll instanceof ImmutableCollections.AbstractImmutableList) {
return (List)coll;
} else {
return (List)List.of(coll.toArray());
}
}
- 实例
@Test(expected = UnsupportedOperationException.class)
public void testCollectionCopyOf(){
List list = IntStream.rangeClosed(1,10)
.mapToObj(i -> "num"+i)
.collect(Collectors.toList());
List newList = List.copyOf(list);
newList.add("not allowed");
}
Collectors新增了toUnmodifiableList, toUnmodifiableSet,以及 toUnmodifiableMap方法
@Test(expected = UnsupportedOperationException.class)
public void testCollectionCopyOf(){
List list = IntStream.rangeClosed(1,10)
.mapToObj(i -> "num"+i)
.collect(Collectors.toUnmodifiableList());
list.add("not allowed");
}
小结
java10最主要的新特性,在语法层面就属于Local-Variable Type Inference,而在jvm方面307: Parallel Full GC for G1以及317: Experimental Java-Based JIT Compiler都比较重磅,值得深入研究。
doc
- JDK 10 Features
- Introducing Java SE 10(
官方解读
) - What's New in JDK 10 - New Features and Enhancements(
官方细项解读
) - JDK-8140281 : (opt) add no-arg orElseThrow() as preferred alternative to get()
- JDK-8177290 : add copy factory methods for unmodifiable List, Set, Map
Java11新特性
11版本是8版本之后第一个长支持的版本,可以考虑从8直接升级到11版本,11版本涵盖了9和10的版本特性,并做了优化。
版本号
java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
- General-Availability Release版本是基于tag为jdk-11+28的版本编译
- 从version信息可以看出是build 11+28
特性列表
- 181: Nest-Based Access Control
相关解读Java Nestmate稳步推进,Specification for JEP 181: Nest-based Access Control
简单的理解就是Class类新增了getNestHost,getNestMembers方法
- 309: Dynamic Class-File Constants
相关解读Specification for JEP 309: Dynamic Class-File Constants (JROSE EDITS)
jvm规范里头对Constant pool新增一类CONSTANT_Dynamic
- 315: Improve Aarch64 Intrinsics
对于AArch64处理器改进现有的string、array相关函数,并新实现java.lang.Math的sin、cos、log方法
- 318: Epsilon: A No-Op Garbage Collector
引入名为Epsilon的垃圾收集器,该收集器不做任何垃圾回收,可用于性能测试、短生命周期的任务等,使用-XX:+UseEpsilonGC开启
- 320: Remove the Java EE and CORBA Modules(
重磅
)
将java9标记废弃的Java EE及CORBA模块移除掉,具体如下:(1)xml相关的,java.xml.ws, java.xml.bind,java.xml.ws,java.xml.ws.annotation,jdk.xml.bind,jdk.xml.ws被移除,只剩下java.xml,java.xml.crypto,jdk.xml.dom这几个模块;(2)java.corba,java.se.ee,java.activation,java.transaction被移除,但是java11新增一个java.transaction.xa模块
- 321: HTTP Client (Standard)(
重磅
)
相关解读java9系列(六)HTTP/2 Client (Incubator),HTTP Client Examples and Recipes,在java9及10被标记incubator的模块jdk.incubator.httpclient,在java11被标记为正式,改为java.net.http模块。
- 323: Local-Variable Syntax for Lambda Parameters
相关解读New Java 11 Language Feature: Local-Variable Type Inference (var) extended to Lambda Expression Parameters
允许lambda表达式使用var变量,比如(var x, var y) -> x.process(y),如果仅仅是这样写,倒是无法看出写var有什么优势而且反而觉得有点多此一举,但是如果要给lambda表达式变量标注注解的话,那么这个时候var的作用就突显出来了(@Nonnull var x, @Nullable var y) -> x.process(y)
- 324: Key Agreement with Curve25519 and Curve448
使用RFC 7748中描述的Curve25519和Curve448实现key agreement
- 327: Unicode 10
升级现有的API,支持Unicode10.0.0
- 328: Flight Recorder
相关解读Java 11 Features: Java Flight Recorder
Flight Recorder以前是商业版的特性,在java11当中开源出来,它可以导出事件到文件中,之后可以用Java Mission Control来分析。可以在应用启动时配置java -XX:StartFlightRecording,或者在应用启动之后,使用jcmd来录制,比如
$ jcmd JFR.start
$ jcmd JFR.dump filename=recording.jfr
$ jcmd JFR.stop
- 329: ChaCha20 and Poly1305 Cryptographic Algorithms
实现 RFC 7539的ChaCha20 and ChaCha20-Poly1305加密算法
- 330: Launch Single-File Source-Code Programs(
重磅
)
相关解读Launch Single-File Source-Code Programs in JDK 11
有了这个特性,可以直接java HelloWorld.java来执行java文件了,无需先javac编译为class文件然后再java执行class文件,两步合成一步
- 331: Low-Overhead Heap Profiling
通过JVMTI的SampledObjectAlloc回调提供了一个开销低的heap分析方式
- 332: Transport Layer Security (TLS) 1.3(
重磅
)
支持RFC 8446中的TLS 1.3版本
- 333: ZGC: A Scalable Low-Latency Garbage Collector(Experimental)(
重磅
)
相关解读JDK11的ZGC小试牛刀,一文读懂Java 11的ZGC为何如此高效
- 335: Deprecate the Nashorn JavaScript Engine
相关解读Oracle弃用Nashorn JavaScript引擎,Oracle GraalVM announces support for Nashorn migration
废除Nashorn javascript引擎,在后续版本准备移除掉,有需要的可以考虑使用GraalVM
- 336: Deprecate the Pack200 Tools and API
废除了pack200以及unpack200工具以及java.util.jar中的Pack200 API。Pack200主要是用来压缩jar包的工具,不过由于网络下载速度的提升以及java9引入模块化系统之后不再依赖Pack200,因此这个版本将其移除掉。
细项解读
上面列出的是大方面的特性,除此之外还有一些api的更新及废弃,主要见What's New in JDK 11 - New Features and Enhancements以及90 New Features (and APIs) in JDK 11,这里举几个例子。
添加项
- Collection.toArray(IntFunction)
@Test
public void testCollectionToArray(){
Set names = Set.of("Fred", "Wilma", "Barney", "Betty");
String[] copy = new String[names.size()];
names.toArray(copy);
System.out.println(Arrays.toString(copy));
System.out.println(Arrays.toString(names.toArray(String[]::new)));
}
Collection类新增toArray(IntFunction)的default方法,可以直接通过传入IntFunction告知要转换的目标类型
- String.strip
@Test
public void testStrip(){
String text = " \u2000a b ";
Assert.assertEquals("a b",text.strip());
Assert.assertEquals("\u2000a b",text.trim());
Assert.assertEquals("a b ",text.stripLeading());
Assert.assertEquals(" \u2000a b",text.stripTrailing());
}
java11对String类新增了strip,stripLeading以及stripTrailing方法,除了strip相关的方法还新增了isBlank、lines、repeat(int)等方法
- 添加了Google Trust Services GlobalSign Root Certificates
- 添加了GoDaddy Root Certificates
- 添加了T-Systems, GlobalSign and Starfield Services Root Certificates
- 添加了Entrust Root Certificates
移除项
- 移除了com.sun.awt.AWTUtilities
- 移除了sun.misc.Unsafe.defineClass,使用java.lang.invoke.MethodHandles.Lookup.defineClass来替代
- 移除了Thread.destroy()以及 Thread.stop(Throwable)方法
- 移除了sun.nio.ch.disableSystemWideOverlappingFileLockCheck、sun.locale.formatasdefault属性
- 移除了jdk.snmp模块
- 移除了javafx,openjdk估计是从java10版本就移除了,oracle jdk10还尚未移除javafx,而java11版本则oracle的jdk版本也移除了javafx
- 移除了Java Mission Control,从JDK中移除之后,需要自己单独下载
- 移除了这些Root Certificates :Baltimore Cybertrust Code Signing CA,SECOM ,AOL and Swisscom
废弃项
- 废弃了Nashorn JavaScript Engine
- 废弃了-XX+AggressiveOpts选项
- -XX:+UnlockCommercialFeatures以及-XX:+LogCommercialFeatures选项也不再需要
- 废弃了Pack200工具及其API
小结
- java11是java改为6个月发布一版的策略之后的第一个LTS(
Long-Term Support
)版本(oracle版本才有LTS
),这个版本最主要的特性是:在模块方面移除Java EE以及CORBA模块,在JVM方面引入了实验性的ZGC,在API方面正式提供了HttpClient类。 - 从java11版本开始,不再单独发布JRE或者Server JRE版本了,有需要的可以自己通过jlink去定制runtime image
doc
- JDK11
- JDK11 Features
- Introducing Java SE 11(
官方解读
) - JDK 11 Release Notes(
官方细项解读
) - What is new in Java 11 ?
- Java Nestmate稳步推进
- Specification for JEP 181: Nest-based Access Control
- Specification for JEP 309: Dynamic Class-File Constants (JROSE EDITS)
- Java 11 Features: Java Flight Recorder
- java9系列(六)HTTP/2 Client (Incubator)
- Java 11: Standardized HTTP Client API
- java.net.http javadoc
- HTTP Client Examples and Recipes
- New Java 11 Language Feature: Local-Variable Type Inference (var) extended to Lambda Expression Parameters
- JDK11的ZGC小试牛刀
- 一文读懂Java 11的ZGC为何如此高效
- Oracle弃用Nashorn JavaScript引擎
- Oracle GraalVM announces support for Nashorn migration
- JDK 11: New Default Collection Method toArray(IntFunction)
- 90 New Features (and APIs) in JDK 11
- APIs To Be Removed from Java 11
- Java 11 String API Updates
Java12新特性
12版本也是一个过渡版本
- 支持原生字符串,ts/js等语言早已支持,java再不支持就说不过去了,不过这个语法真的是方便,我预言Java12以后模版引擎将成为过去式。
- 转译支持
- 边距处理
原生字符串支持
Java中书写多行字符串和特殊转义字符时非常不方便和不直观,Java 12将会引入原生字符串(Raw String Literals)解决这一问题。
Java 12之前的写法:
String html = "\n" + " \n" +
" Hello World.
\n" +
" \n" + "\n";
Java 12的写法:
String html = ` Hello World.
`;
转义支持(Escapes)
为了原生字符串中使用转义字符,String class中增加了两个方法:
public String unescape()
public String escape()
以下结果都返回true:
boolean b0 = `\n`.equals("\\n"); boolean b1 = `\n`.unescape().equals("\n"); boolean b2 = `\n`.length == 2; boolean b3 = `\n`.unescape().length == 1;
边距管理(Margin Management)
为了处理多行字符串左边距的问题,String class中增加了两个方法:
public String align()
public String indent(int n)
align方法用来去掉开头和结尾的空白行,保持每行的相对缩进。
indent方法用来控制每行开头增加或减少几个空格,n为正数时增加,n为负数时减少。
通常会组合两者使用,align().indent(n)
,所以另外提供了一个组合方法:
public String align(int n)
其他特性见参考:https://openjdk.java.net/projects/jdk/12/