Java8到21新特性
只记录实际开发中较为实用的特性。
var
使用var自动推断局部变量类型
11提供了新的Http客户端
使用上更便捷简单,支持Http1.1、Http2。也支持异步请求。这里直接把JDK中的示例代码扒出来看看就行了。
还有一些扩展的东西。像什么BodyHandler、BodySubscriber等等。感兴趣可以去看看
- 同步示例
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
.followRedirects(Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
.authenticator(Authenticator.getDefault())
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body()); }
- 异步示例
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://foo.com/"))
.timeout(Duration.ofMinutes(2))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofFile(Paths.get("file.json")))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println); }
改善Optional
java8的Optional,仅仅是对一个可能为空的对象的封装。
在Java9中,对其进行了进一步封装。
在java11中增加了isEmpty方法,逻辑与isPresent相反。
- Optional可以直接转换成stream,(内部会有判空处理)
Optional.ofNullable("").stream().xxxx
- ifPresentOrElse直接提供两个函数式实现,分别用于处理有值和无值的情况
s.ifPresentOrElse(v -> {sout(v)}, ()->{sout(没有值)});
- or 比ifPresentOrElse更直接,当前Optional 内部为空时,提供备选的Optional对象
Optional<Object> empty = Optional.empty();
Optional<String> s1 = Optional.ofNullable("123");
Optional<Object> or = empty.or(() -> s1);
改善stream
java9中新增的2个功能方法
- takeWhile:一直取值,直到指定条件为false,结束取值
- dropWhile:一直跳过,直到指定条件为fase,开始取值(后续值不再判断,直接取后续所有值)
java16中增加了一些mapMultiToxxx方法
用于将多个值转为对应类型的Stream
16还提供了便捷转stream转list的方法(直接.toList())
增强switch
现在的swtich给人的感觉就和if-else if-…差不多,只能进行等值判断分支。
增强后的switch,改动该说不说还是有点大。刚开始使用可能还有点不习惯。
- 区别最大的一点就是可以有返回值了。(当然,如果有返回值,那么每个分支都有返回值)
- 而且不仅仅能进行值匹配,还能进行类型匹配(当参数是夫类型)
- 甚至进行多条件匹配(多个条件OR关系 使用 | 分割)
接口私有方法
在java8中,接口增加了默认方法和静态方法。
java9中,又增加了私有方法,可以对接口中的代码提取成方法。
到现在,接口的能力感觉在向抽象类靠拢,但是,显著的区别在于,抽象类可以是有状态的(存在成员变量),接口则只定义方法或者说是规范。
Text blocks
文本块,用于定义原生字符串,无须再搞各种转义。而且还支持变量注入(${变量名})
String json = """
{
"k":123,
"v":"abc"
}
""";
JSONObject jsonObject = JSON.parseObject(json);
System.out.println(jsonObject.get("k"));
record
final 字段 + get + tostring
目前很多三方库未适配,运用场景有限
instanceof模式匹配
Object o = "1";
if (o instanceof String s) {
System.out.println(s.length());
}
Sealed class
限定类/接口 的子类,在结构设计上有场景,通常保护结构不被破坏。
举例:
接口A限定实现类只能为 A1
public sealed interface A permits A1 {
void test();
}
A1可以实现A
public non-sealed class A1 implements A{
@Override
public void test() {
System.out.println("a1");
}
}
A2则无法实现A
public final class A2 implements A{
@Override
public void test() {
System.out.println("a2");
}
}
编译报错
tips
对于重写了 sealed 的类,这个标识符会默认传下来
要摆脱这个限制,此类须通过以下任一种显式定义以消除影响
- 定义为最终实现类 public final class A11 extends A1
- 声明为 非密封类 public non-sealed class A1 implements A
- 当前类为抽象类或接口,继续将 sealed 传下去,同时指定子类 public sealed class A1 implements A11
sealed 必须指定其子类,杜绝没用的废物接口。走到最后只有两种类;一是 final class;一是 non-sealed class
NullPointerException 优化
优化了空指针异常时的异常信息,对排查错误信息更友好
示例:
String s = null;
String s2 = "s2";
System.out.println(s.length() + s2.length());
现在的异常信息
就一个行数,如果一行中有多个调用,无法确定具体是哪个调用引起空指针。优化后的异常信息
明确提示,哪个调用引起的空指针。