jdk8-特性概述

183 阅读3分钟

这是我参与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中指定的子集

image-20211115045503486

compact1compact2 Additionscompact3 Additions
java.iojava.rmijava.lang.instrument
java.langjava.rmi.activationjava.lang.management
java.lang.annotationjava.rmi.dgcjava.security.acl
java.lang.invokejava.rmi.registryjava.util.prefs
java.lang.refjava.rmi.serverjavax.annotation.processing
java.lang.reflectjava.sqljavax.lang.model
java.mathjavax.rmi.ssljavax.lang.model.element
java.netjavax.sqljavax.lang.model.type
java.niojavax.transactionjavax.lang.model.util
java.nio.channelsjavax.transaction.xajavax.management
java.nio.channels.spijavax.xmljavax.management.loading
java.nio.charsetjavax.xml.datatypejavax.management.modelmbean
java.nio.charset.spijavax.xml.namespacejavax.management.monitor
java.nio.filejavax.xml.parsersjavax.management.openmbean
java.nio.file.attributejavax.xml.streamjavax.management.relation
java.nio.file.spijavax.xml.stream.eventsjavax.management.remote
java.securityjavax.xml.stream.utiljavax.management.remote.rmi
java.security.certjavax.xml.transformjavax.management.timer
java.security.interfacesjavax.xml.transform.domjavax.naming
java.security.specjavax.xml.transform.saxjavax.naming.directory
java.textjavax.xml.transform.staxjavax.naming.event
java.text.spijavax.xml.transform.streamjavax.naming.ldap
java.timejavax.xml.validationjavax.naming.spi
java.time.chronojavax.xml.xpathjavax.security.auth.kerberos
java.time.formatorg.w3c.domjavax.security.sasl
java.time.temporalorg.w3c.dom.bootstrapjavax.sql.rowset
java.time.zoneorg.w3c.dom.eventsjavax.sql.rowset.serial
java.utilorg.w3c.dom.lsjavax.sql.rowset.spi
java.util.concurrentorg.xml.saxjavax.tools
java.util.concurrent.atomicorg.xml.sax.extjavax.xml.crypto
java.util.concurrent.locksorg.xml.sax.helpersjavax.xml.crypto.dom
java.util.functionjavax.xml.crypto.dsig
java.util.jarjavax.xml.crypto.dsig.dom
java.util.loggingjavax.xml.crypto.dsig.keyinfo
java.util.regexjavax.xml.crypto.dsig.spec
java.util.spiorg.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获取参数名称

集合

  1. 新增java.util.stream包下的Stream API
  2. Collections工具类中添加Stream相关API
  3. HashMap、LinkedHashMap、ConcurrentHashMap.红黑树优化

时间日期

java.time中新增时间日期API

java.lang 和 java.util

两个包下新增API

  1. 并行数组排序:Arrays.parallelSort()
  2. Base64编解码:通过Base64中的静态方法
  3. 无符号算术支持

并发(Concurrency)

在以下包或类中添加新的API

  1. java.util.concurrent
  2. ConcurrentHashMap
  3. java.util.concurrent.atomic
  4. java.util.concurrent.ForkJoinPool
  5. java.util.concurrent.locks

HotSpot

  • 硬件加密 AES

启用:-XX:+UseAES -XX:+UseAESIntrinsics

禁用:-XX:-UseAES -XX:-UseAESIntrinsics

  • 移除 PermGen
  • 用于方法调用的字节码指令支持 Java 编程语言中的默认方法(Default methods)。

下期预告

lambda 表达式 和 方法引用(Method references)