这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
欢迎关注公众号OpenCoder,来和我做朋友吧~❤😘😁🐱🐉👀
前言
前几篇文章,给大家分享了JDK 17中的一些新特性。
接下来的内容,我们继续围绕JDK各版本的特性进行讨论学习。
之前的文章中提到过,目前有三个版本(8、11、17)是长期维护(LTS)版本;而目前绝大多数企业使用的版本还是JDK8。
本期我们一起看一下JDK8有哪些特性。
语法
Lambda表达式
它们使您能够将功能视为方法参数,或将代码视为数据。 Lambda 表达式让您可以更简洁地表达单方法接口(称为函数式接口)的实例。
List<String> list = new ArrayList<>(Arrays.asList("a","bb","ccc"));
list.removeIf(s -> s.length() == 3);
System.out.println(list);
方法引用(Method references)
为已有名称的方法提供易于阅读的 lambda 表达式。
List<String> list = new ArrayList<>(Arrays.asList("a","bb","ccc"));
// 方法引用: 谁::做什么
list.forEach(System.out::println);
默认方法(Default methods)
允许将新功能添加到接口中,并确保与为这些接口的旧版本编写的代码的兼容性。例如:List接口中的replaceAll方法
/*
* ......
* @since 1.8
*/
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
重复注解(Repeating Annotations)
提供了将相同注解类型多次应用于相同声明或类型使用的能力。
// 定义注解Schedule
// @Repeatable为jdk中的元注解,表示Schedule可以重复使用
@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}
// 使用
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }
类型注解(Type Annotations)
提供了在使用类型的任何地方应用注解的能力,而不仅仅是在声明上。与插件一起使用,此功能可以改进代码的类型检查。
在 Java SE 8 发布之前,注解只能应用于声明。从 Java SE 8 版本开始,注解也可以应用于任何类型的使用。例如:
-
类的实例化
- new @Interned MyObject();
-
类型转换
- myString = (@NonNull String) str;
-
接口实现
- class UnmodifiableList implements @Readonly List<@Readonly T> { ... }
-
抛异常
- void monitorTemperature() throws @Critical TemperatureException { ... }
-
示例
// 需要使用插件checker framework: https://checkerframework.org/ // 也可以自定义插件 // @NonNull 表示String s不能是null 否则在编译时就会由插件给出错误 public static void test(@NonNull String s){ System.out.println(s); } public static void main(String[] args) { test(null); } // 编译结果 test(null); ^ found : null (NullType) required: @Initialized @NonNull String
改进类型推断(type inference)
Java 编译器利用目标类型来推断泛型方法调用的类型参数。
List<String> stringList = new ArrayList<>();
stringList.add("A");
// addAll(Collection<? extends String>) 目标类型是Collection<? extends String>
// Arrays.asList() 返回 List<T>
// 编译器根据Collection<? extends String>自动推断T为String
stringList.addAll(Arrays.asList());
Compact Profiles
该配置定义了Java SE平台API的子集
javac -profile选项,可以选择使用jdk中指定的子集
compact1 | compact2 Additions | compact3 Additions |
---|---|---|
java.io | java.rmi | java.lang.instrument |
java.lang | java.rmi.activation | java.lang.management |
java.lang.annotation | java.rmi.dgc | java.security.acl |
java.lang.invoke | java.rmi.registry | java.util.prefs |
java.lang.ref | java.rmi.server | javax.annotation.processing |
java.lang.reflect | java.sql | javax.lang.model |
java.math | javax.rmi.ssl | javax.lang.model.element |
java.net | javax.sql | javax.lang.model.type |
java.nio | javax.transaction | javax.lang.model.util |
java.nio.channels | javax.transaction.xa | javax.management |
java.nio.channels.spi | javax.xml | javax.management.loading |
java.nio.charset | javax.xml.datatype | javax.management.modelmbean |
java.nio.charset.spi | javax.xml.namespace | javax.management.monitor |
java.nio.file | javax.xml.parsers | javax.management.openmbean |
java.nio.file.attribute | javax.xml.stream | javax.management.relation |
java.nio.file.spi | javax.xml.stream.events | javax.management.remote |
java.security | javax.xml.stream.util | javax.management.remote.rmi |
java.security.cert | javax.xml.transform | javax.management.timer |
java.security.interfaces | javax.xml.transform.dom | javax.naming |
java.security.spec | javax.xml.transform.sax | javax.naming.directory |
java.text | javax.xml.transform.stax | javax.naming.event |
java.text.spi | javax.xml.transform.stream | javax.naming.ldap |
java.time | javax.xml.validation | javax.naming.spi |
java.time.chrono | javax.xml.xpath | javax.security.auth.kerberos |
java.time.format | org.w3c.dom | javax.security.sasl |
java.time.temporal | org.w3c.dom.bootstrap | javax.sql.rowset |
java.time.zone | org.w3c.dom.events | javax.sql.rowset.serial |
java.util | org.w3c.dom.ls | javax.sql.rowset.spi |
java.util.concurrent | org.xml.sax | javax.tools |
java.util.concurrent.atomic | org.xml.sax.ext | javax.xml.crypto |
java.util.concurrent.locks | org.xml.sax.helpers | javax.xml.crypto.dom |
java.util.function | javax.xml.crypto.dsig | |
java.util.jar | javax.xml.crypto.dsig.dom | |
java.util.logging | javax.xml.crypto.dsig.keyinfo | |
java.util.regex | javax.xml.crypto.dsig.spec | |
java.util.spi | org.ietf.jgss | |
java.util.stream | ||
java.util.zip | ||
javax.crypto | ||
javax.crypto.interfaces | ||
javax.crypto.spec | ||
javax.net | ||
javax.net.ssl | ||
javax.script | ||
javax.security.auth | ||
javax.security.auth.callback | ||
javax.security.auth.login | ||
javax.security.auth.spi | ||
javax.security.auth.x500 | ||
javax.security.cert |
API
方法参数反射
javac -parameters 可以让.class文件存储方法的参数名
然后使用反射提供的API获取参数名称
集合
- 新增java.util.stream包下的Stream API
- Collections工具类中添加Stream相关API
- HashMap、LinkedHashMap、ConcurrentHashMap.红黑树优化
时间日期
java.time中新增时间日期API
java.lang 和 java.util
两个包下新增API
- 并行数组排序:Arrays.parallelSort()
- Base64编解码:通过Base64中的静态方法
- 无符号算术支持
并发(Concurrency)
在以下包或类中添加新的API
- java.util.concurrent
- ConcurrentHashMap
- java.util.concurrent.atomic
- java.util.concurrent.ForkJoinPool
- java.util.concurrent.locks
HotSpot
- 硬件加密 AES
启用:-XX:+UseAES -XX:+UseAESIntrinsics
禁用:-XX:-UseAES -XX:-UseAESIntrinsics
- 移除 PermGen
- 用于方法调用的字节码指令支持 Java 编程语言中的默认方法(Default methods)。
下期预告
lambda 表达式 和 方法引用(Method references)