Java 新特性
Java 8
Lambda & Functional Interface
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
public class LambdaExamples {
@Test
public void test(){
new Thread(() -> {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
误区: 通过匿名函数生成Runnable
对象, 传递给 Thread
。
实际上: 内部优化直接调用了匿名函数(Invokedynamic
命令), 没有写死在字节码中。
方法引用 ::
操作符
public class MethodReference {
@Test
public void test(){
// 1-2-3-4-5
var val = List.of(1,2,3,4,5).stream()
.map(Object::toString)
.map(Integer::new)
.reduce((a,b)->a+b);
System.out.println(val);
}
}
Stream
一个 Monad
. 函数式, 流计算. Monad
是一类对象.
Optional<T>
一个 Monad. 流计算, 减少空值检查.
接口的方法(static, default, private)
private
是jdk9
的.
Java8 Nashorn JavaScript, 在 JDK11 的准备弃用了
本地化日期处理升级
public class Local {
@Test
public void test_date(){
// 2022年2月22日
var date = LocalDate.of(2022, 2, 22);
// 10:55:59
var time = LocalTime.of(10, 55, 59);
// 当前时间
var datetime = LocalDateTime.of(date, time);
var zoneDT = ZonedDateTime.of(datetime, ZoneId.of("Asia/Shanghai"));
}
}
在新的API中, 不再允许mutable
操作(非线程安全). 变成immutable
了.
内置了Base64工具
对0~255
之间的字符, Base64编码是以4个可见字符去描述3个字符, 会增加数据的体积, 但是因为所有字符都可以读, 用Base64描述的字符串, 在URL, XML中都不会被转义.
Java 9
模块系统(Jar Hell, jar包地狱)
交互式编程环境(JShell)
新的HTTP 2.0 Client
. HTTP 2.0, 兼容 HTTP 1.0, 主要从性能角度进行了调优.
- 多个HTTP请求/返回在通一个TCP请求多路复用(客户端要负责实现多路复用)
- 头部压缩算法(客户端要负责解压)
- Server Push: 服务器可能会给客户端额外的文件(浏览器要负责识别, 并缓存这些文件, 客户端不一定要实现)
改进了Javadoc
# 可生成符合标准的HTML5页面
javadoc -d foo -html5 MyHelloWorld.java
支持multirelease jar
包
javac --release 9 java9/hello/xxx.java
javac --release 8 java8/hello/xxx.java
最后用 jar 可以产生不同版本的 jar 包.
jar -c -f xxx.jar -C java8 . --release -c java9 .
这样 xxx.jar 中同时有 java8 和 java9 的程序.
集合的工厂方法
var set = Set.of("Apple");
var list = List.of("Apple");
var Map = Map.of("String", 5);
增强 ProcessHandler
进程是执行文件的副本, 因为本来是在磁盘中的.
Stream API
增加了方法
takeWhile
take while != 7 is hold. 就是不等于7就拿, 否则就停下了
Stream.of(2, 3, 1, 7, 9).takeWhile(x->x!=7).collect(Collections.toList()); // [2,3,1]
dropWhile
drop while != 7 is hold. 就是不等于7就丢弃, 否则就停下了
Stream.of(2, 3, 1, 7, 9).dropWhile(x->x!=7).collect(Collections.toList()); // [7,9]
iterate
构造迭代
Stream.iterate(
10, // 初始值
x -> x < 100, // 终结断言
x -> x + 2 // 递推函数
).collect(Collectors.toList());
ofNullable
// java9 之前如果是 null 是报错的.
// 希望是 子函子, 总是能返回自己的类型. 把产生副作用的数据封装起来.
Stream.ofNullable(null); // Stream.empty()
<> 钻石操作符语法优化
允许匿名类使用钻石操作符.
CompletableFuture 改进
CompletableFuture 是 java
异步计算能力的核心。
completeOnTimeout 方法
@Test
public void test() throws ExecutionException, InterruptedException {
var future = new CompletableFuture<>();
Executors.newCachedThreadPool().submit(() -> {
// Thread.sleep(1000); 原来使用这个
// future.complete("Hello");
future.completeOnTimeout("Hello", 1000, TimeUnit.MILLISECONDS);
return null;
});
// sync. method blocking...
var value = future.get();
System.out.println(value);
}
添加直接成功/失败的future工厂方法
@Test
public void test2() throws ExecutionException, InterruptedException {
var successFuture = CompletableFuture.completedFuture("Hello");
var failFuture = CompletableFuture.failedFuture(new InterruptedException());
System.out.println(successFuture.get());
if(failFuture.isCompletedExceptionally()) {
System.out.println("error"); // print
}
System.out.println(failFuture.get()); // Exception
}
try-with-resources 的改进
对实现 closeable
的对象可以直接进行 try.
Java 10
局部变量类型推断
var list = new LinkedList<Integer>();
程序可读, 在几个维度
- 命名.
- 程序结构. 足够领域化, 关注分离点好.
JDK 代码仓库整理
所有JDK代码不再使用8个仓库管理, root, corba, hotspot, jaxp, jaxws, jdk, langtools, nashorn
统一成为一个仓库.
主要是解决原子提交问题: 一个功能可能需要更新多个代码仓库.
G1 增加并行能力
在 mark-sweep-compact
的GC算法上, 增加并行能力.
优化: 应用测序数据共享
Application Data Sharing(ADS) : 允许多个 JVM
实例共享用到的类. 这些类以共享内存的形式存在. 这样对于运行多个 JVM 的机器, 可以节省内存空间以及类的加载速度.
计划移除 JNI 头生成工具
通常在 Android 开发中, 需要生成一个C/C++的头文件, 是需要用javah
来生成的。
以后 JNI
的能力会被 Panama
项目替代,一个专门为非 Java 语言提供接口的库,提升 JVM
和外部代码和数据的关联。
增加了实验性的 Graal 编译器
可以配置参数开启
-XX:+UnlockExperimentVMOptions -XX:+UseJVMCompiler
是一款支持 JIT
和 AOT
的编译器.
- JIT(Just In Time) : 一边编译一边执行, 执行完第一次之后, 下一次不需要编译.
- AOT(Ahead Of Time) : 类似C/C++那样, 先编译成机器码, 再执行. 是机器码, 绕过了JVM的bytecode.
Java 11
引入 NestedMembers 概念
嵌套类和它的父亲作为一组NestedMembers, 可以互相访问元数据.
public class Nested {
class A{
private String name = "123";
}
class B{
public void bar() throws NoSuchFieldException {
System.out.println(A.class.getDeclaredField("name"));
}
}
@Test
public void test() throws NoSuchFieldException {
var b = new B();
b.bar();
// name
System.out.println(Arrays.toString(A.class.getNestMembers()));
// [Nested, A, B] 组
System.out.println(A.class.getNestHost());
// Nested 宿主
System.out.println(Arrays.toString(B.class.getNestMembers()));
// [Nested, A, B]
System.out.println(B.class.getNestHost());
// Nested
}
}
增加无操作GC回收器 Epsilon
Epsilon
美[ˈepsɪlɑːn]不会进行垃圾回收操作, 就是不进行GC.
使用-XX:+UseEpsilonGC
开启.
Epsilon
虽然不GC, 但是仍然承担着内存分配的工作.
优点
- 对于开发者明确知道不需要GC的程序有助于减少延迟
- 对于性能测试, 压力测试的场景, 可以忽略GC带来的延迟. 希望GC不会影响程序的测试.
Lambda 优化, 允许使用 var 定义匿名函数形参
优化, 增加字符串处理函数
isBlank()
, strip()
, stripTrailing()
, repeat()
, lines().count()
.