java8新特性总结

浮生半日闲 发布于 2023-02-16 5 次阅读


https://my.oschina.net/spinachgit/blog/1606567

java8是2014年3月份正式发布的,带来了诸多的新特性(官网地址:https://www.oracle.com/java/technologies/javase/8-whats-new.html),下面来一一进行介绍。

1、针对java语言

1.1 Lambda表达式

Lambda表达式是一种新的语言特性,它能够把函数作为方法的参数或将代码作为数据。能够更紧凑的表达单个方法接口(称为函数接口)的实例。

/**
*  自定义函数式接口
*  注意:
*    1、使用@FunctionalInterface注解(非必须)
*    2、函数的方法只有1个
**/
@FunctionalInterface
public interface OperationAdd {

    /**
     *  执行方法
     * @param a 参数1
     * @param b 参数2
     * @return         
     */
    int execute(int a, int b);
}
/**
 * 方法测试
 **/
public class test {

    public static void main(String[] args) {
        /**
         * 申明lambda表达式
         * 1、方法体为表达式,该表达式的值作为返回值返回。 (parameters) -> expression
         * 2、方法体为代码块,必须用 {} 来包裹起来,且需要一个 return 返回 值,但若函数式接 口里面方法返回值是 void,则无需返回值。
         */
        OperationAdd add = (a, b) -> a + b;

        OperationAdd add2 = (a, b) -> {
            return a + b;
        };

        int result = add.execute(1, 2);
    }
}

1.2 方法引用

方法引用为已具有名称的方法提供了易于读取的lambda表达式。

方法引用使用"::"表示,左边是具体的类,右边是调用的具体的方法。使用lambda表达式和方法引用的效果是等价的,但是方法引用看起来效果会更简洁些。

List<String> list = new ArrayList<String>(){{
    add("listA");
    add("listD");
    add("listB");
    add("listC");
}};
list.forEach(item -> System.out.println(item));
list.forEach(System.out::println);

1.3 默认方法

默认方法指的是可以在接口中直接添加,而不需要后续实现该接口的类都重写该方法。

public interface Constant<T> {
    T getValue();

    default String getDescription() {
        return this.getValue().toString();
    }
}

1.4 重复注解

重复注解允许在同一个元素上使用多个相同类型的注解。

在java8之前如果需要添加多个注解,方式如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface TestAnnotation {

    String value();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface TestAnnotationArray {

    TestAnnotation[] value();
}

@TestAnnotationArray({
        @TestAnnotation("1"),
        @TestAnnotation("2")
})
public class TestAnnotationMain {
}

引入了重复注解后,可以修改成:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
@Repeatable(TestAnnotationArray.class)
public @interface TestAnnotation {

    String value();
}


@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Inherited
public @interface TestAnnotationArray {

    TestAnnotation[] value();
}

@TestAnnotation("1")
@TestAnnotation("2")
public class TestAnnotationMain {
}

说明:通过查看.class文件,我们可以发现java8的编译器会自动将重复注解解析成以前的方式。

1.5 类型注解

java8为ElementType增加了TYPE_PARAMETER和TYPE_USE2个枚举值,使用这2个定义的注解就是类型注解。

类型注解可以在任何使用类型的地方使用,而不仅仅是在申明上。

1.6 改善类型推断

1.7 方法参数反射

可以通过method.getParameters()直接拿到方法的参数。

1.8 标准编码和解码

实现了Base64编解码的API。

// 编码
String code = Base64.getEncoder().encodeToString("编码".getBytes());
// 解码
String decode = new String(Base64.getDecoder().decode(code));

2、针对集合

2.1 StreamAPI

java8中提供了新包java.util.stream,这个包里面提供了StreamAPI的功能,支持函数式的操作去处理流中的元素。集合API中已经整合了StreamAPI,支持对集合进行批量操作。

List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }

        System.out.println(list.stream().map(item -> item * 2).collect(Collectors.toList()));
        System.out.println(list.stream().sorted((item1, item2) -> item1 - item2).collect(Collectors.toList()));

2.2 HashMaps性能改进

具有密钥冲突的HashMaps的性能改进

3、安全方面

3.1 默认情况下启用客户端TLS 1.2

3.2 AccessController.doPrivileged的新变体,它使代码能够断言其特权的子集,而不阻止对堆栈进行完全遍历以检查其他权限

3.3 更强大的基于密码的加密算法

3.4 JSSE服务器中的SSL/TLS服务器名称指示(SNI)扩展支持

3.5 对AEAD算法的支持:SunJCE提供程序得到增强,支持AES/GCM/NoPadding密码实现以及GCM算法参数。SunJSSE提供程序经过增强,支持基于AEAD模式的密码套件。

3.6 KeyStore增强功能,包括新的Domain KeyStore类型java.security.DomainLoadStoreParameter,以及keytool实用程序的新命令选项-importpassword

3.7 SHA-224消息摘要

3.8 增强了对NSA Suite B加密的支持

3.9 更好地支持高熵随机数生成

3.10 提供了java.security.cert.PKIXRevocationChecker,用于配置X.509证书的吊销检查

3.11 用于Windows的64位PKCS11

3.12 Kerberos 5 Replay缓存中的新rcache类型

3.13 支持Kerberos 5协议转换和受限委派

3.14 默认情况下禁用Kerberos 5弱加密类型

3.15 GSS-API/Kerbos5机制的未绑定SASL

3.16 用于多个主机名的SASL服务

3.17 JNI桥接到Mac OS X上的本地JGSS

3.18 在SunJSSE提供程序中支持更强强度的临时DH密钥

3.19 支持JSSE中的服务器端密码套件首选项自定义

4、国际化

4.1 Unicode增强功能,包括对Unicode 6.2.0的支持

4.2 采用Unicode CLDR数据和java.local.providers系统属性

4.3 新的Calendar和Locale APIs

// 获取本地日期
LocalDate localDate = LocalDate.now();
// 获取2023年第30天
localDate = LocalDate.ofYearDay(2023, 30);
// 指定日期
localDate = LocalDate.of(2023, Month.FEBRUARY, 2);

// 当前时间
LocalTime localTime = LocalTime.now();
// 当前日期和时间
LocalDateTime localDateTime = LocalDateTime.now();
// 获取系统默认时区
Clock clock = Clock.systemDefaultZone();

4.4 能够将自定义资源捆绑包安装为扩展

5、IO和NIO

5.1 基于Solaris事件端口机制的Solaris新SelectorProvider实现。需要使用时,将系统属性java.nio.chhannels.spi.Selector设置为值sun.nio.ch.EventPortSelectorProvider。

5.2 减小/jre/lib/charets.jar文件的大小

5.3 ava.lang.String(byte[],*)构造函数和java.lang.String.getBytes()方法的性能改进。

6、jvm

去除了永久代 (PermGen) 被元空间 (Metaspace) 代替

配置:-XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=80m 代替 -XX:PermSize=10m -XX:MaxPermSize=10m

原因:移除永久代是为融合 HotSpot JVM 与 JRockit VM 而做 出的努力,因为 JRockit 没有永久代,不需要配置永久代。

同时,用于方法调用的字节码指令支持Java编程语言中的默认方法。