新特性
Java 8
from 2014
Interface
default 方法 static 方法
虽然有了默认实现, 但跟抽象类还是有些区别的, interface 的方法由 public abstract 修饰, 属性 public static final 这种变动是为了减少接口和实现之间的强约束
函数式接口
有且只有一个抽象方法(可以有多个非抽象方法)的接口 跟 @FunctionalInterface 注解无关 内置的一些:
- Predicate
- Function
- Supplier
- Consumer
- Comparator
Lambda 表达式
是一个匿名函数, java8 允许函数作为参数 也能用::关键字调用, 返回类型必须是 functional-interface
以前想传递函数只能用匿名内部类
参数都是 final, 不能使用 default 方法
编译后可能是个静态方法
Stream
- 参数是函数式接口
- 一个 Sream 只能使用 1 次
- 不改变数据
延迟执行, 等返回一个非 Stream 的方法后才执行
parallelStream 使用 ForkJoin 框架 ForkJoinPool
Optional
可以算一个容器
Optional.ofNullable(zoo).map(o -> o.getDog()).map(d -> d.getAge()).ifPresent(
age -> System.out.println(age)
);- 创建
- of
- ofNullable
- map
- map(Function mapper)
- flatMap(Function mapper)
- 区别在于返回值 Optional 是否从参数中传入
- 判空
- boolean isPresent()
- ifPresent(Consumer consumer)
- get
- orElseGet(Supplier other)
- orElse(T other)
- orElseThrow()
- get()
Date
LocalDate LocalTime LocalDateTime ZonedDateTime DateTimeFormatter
Period.between(d1, d2) 求两个 date 的时间差 Y M D date.toEpochDay() 求直接相差的天数
TemporalAdjusters 调整日期
多重注解
@Retention(RetentionPolicy.RUNTIME)
@interface Hints {
Hint[] value();
}
@Repeatable(Hints.class)
@interface Hint {
String value();
}
// 旧版使用
@Hints({@Hint("hint1"), @Hint("hint2")})
class Person1 {
}
// 新版使用 而且能够通过反射获取到 @Hints 注解
@Hint("hint1")
@Hint("hint2")
class Person2 {
}Java 9
from 2017.9
JShell
玩具
模块化
只要加一个模块描述文件(module-info.java)就能变成一个闭包
module my.module {
//exports 公开指定包的所有公共成员
exports com.my.package.name;
}
module my.module {
//exports…to 限制访问的成员范围
export com.·my.package.name to com.specific.package;
}JDK 被重新组织为 94 个模块;
通过 jlink 可以创建只包含必须的 JDK 模块的运行时镜像
G1
Parallel => G1
List.of()
String
char[] => byte[]
Interface
允许接口有私有方法
try-with-resources
可以使用 effectively-final 变量
final Scanner scanner = new Scanner(System.in);
PrintWriter writter = new PrintWriter(System.out);
try (scanner; writter) {
}Stream & Optional
- 空 stream
- takeWhile() 依次获取满足条件的元素, 遇到第一个不满足的停止
- dropWhile() 从第一个不满足的开始, 获取满足条件的元素, 第一个不满足的也算
个人感觉有点复杂
- iterate()java
// 使用原始 iterate() 方法输出数字 1~10 Stream.iterate(1, i -> i + 1).limit(10).forEach(System.out::println); // 使用新的 iterate() 重载方法输出数字 1~10 Stream.iterate(1, i -> i <= 10, i -> i + 1).forEach(System.out::println); - ifPresentOrElse() 方法接受两个参数 Consumer 和 Runnable,如果 Optional 不为空调用 Consumer 参数,为空则调用 Runnable 参数
- or()java
lookup = name -> finalLookup.lookup(name).or(() -> fallbackLookup.lookup(name));
进程 API
增加 java.lang.ProcessHandle 接口实现对原生进程的管理
// 获取进程
ProcessHandle currentProcess = ProcessHandle.current();java.util.concurrent.Flow
新增了反应式流规范的核心接口
- Publisher SubmissionPublisher implements Publisher
- Subscriber
- Subscription
- Processor
变量句柄
VarHandle 不知道怎么用
平台日志 API
新增了 System.LoggerFinder 用来管理 JDK 使用的日志记录器实现
Java 10
from 2018.3
var
局部变量
垃圾回收器接口
G1 并行 Full GC
G1 的目标是低延迟, 尽可能避免 Full GC. 单线程标记清除慢, 容易触发 Full GC
集合增强
copyOf()
Optional
orElseThrow()
APP CDS
Application Class-Data Sharing
Graal: JIT 编译器
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
将 C2 替换为 Graal
Java 11
from 2018.9
HTTP Client 标准化
String
- isBlank()
- strip()
- stripLeading()
- stripTrailing()
- repeat()
ZGC
Lambda
允许 var
Java 12
from 2019.3
String
- indent(4) 缩进
- transform() "".transform(o -> o + " A")
File
- mismatch(Path path1, Path path2) 文件是否内容相同
NumberFormat
G1 优化
- 混合回收区域集拆分为必选和可选
- 即使返回未使用内存给 OS
Switch
instanceof
if(obj instanceof String str){}Java 13
from 2019.9
ZGC
释放内存
SocketAPI 重构
文本块
Switch
yield 让 switch 返回一个值
private static String descLanguage(String name) {
return switch (name) {
case "Java": yield "object-oriented, platform independent and secured";
case "Ruby": yield "a programmer's best friend";
default: yield name +" is a good language";
};
}Java 14
from 2020.3
空指针定位
-XX:+ShowCodeDetailsInExceptionMessages
record 类
实例化之后不可修改
CMS
移除了 CMS
Java 15
from 2020.9
TreeMap
实现了 Map 的一些 default 方法
Java 16
from 2021.3
Vector
高性能底层向量 API
弹性元空间
Java 17
from 2021.9
伪随机数生成器
RandomGeneratorFactory
密封类
sealed
Java 18
from 2022.3
Java 19
from 2022.9