从Java 8到 Java 17–Java 9

/ 0评 / 0

Java 9 模块系统

Java 9 最大的变化之一是引入了模块系统(Jigsaw 项目)。

模块就是代码和数据的封装体。模块的代码被组织成多个包,每个包中包含Java类和接口;模块的数据则包括资源文件和其他静态信息。

Java 9 模块的重要特征是在其工件(artifact)的根目录中包含了一个描述模块的 module-info.class 文 件。 工件的格式可以是传统的 JAR 文件或是 Java 9 新增的 JMOD 文件。这个文件由根目录中的源代码文件 module-info.java 编译而来。该模块声明文件可以描述模块的不同特征。

在 module-info.java 文件中,我们可以用新的关键词module来声明一个模块,如下所示。下面给出了一个模块com.mycompany.mymodule的最基本的模块声明。

module com.glj.mymodule {
}

Java 9 REPL (JShell)

REPL(Read Eval Print Loop)意为交互式的编程环境。

JShell 是 Java 9 新增的一个交互式的编程环境工具。它允许你无需使用类或者方法包装来执行 Java 语句。它与 Python 的解释器类似,可以直接 输入表达式并查看其执行结果。

执行 JSHELL

$ jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro
jshell>

查看 JShell 命令

输入 /help 可以查看 JShell相关的命令

Java 9 集合工厂方法

Java 9 List,Set 和 Map 接口中,新的静态工厂方法可以创建这些集合的不可变实例。

这些工厂方法可以以更简洁的方式来创建集合。

旧方法创建集合

        Set<String> set = new HashSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        set = Collections.unmodifiableSet(set);
        System.out.println(set);

        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        list = Collections.unmodifiableList(list);
        System.out.println(list);

        Map<String, String> map = new HashMap<>();
        map.put("A","A");
        map.put("B","B");
        map.put("C","C");
        map = Collections.unmodifiableMap(map);
        System.out.println(map);

新方法创建集合

Java 9 中,以下方法被添加到 List,Set 和 Map 接口以及它们的重载对象。

static <E> List<E> of(E e1, E e2, E e3);
static <E> Set<E>  of(E e1, E e2, E e3);
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3);
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
        Set<String> set = Set.of("A","B","C");
        System.out.println(set);

        List<String> list = List.of("A", "B", "C");
        System.out.println(list);

        Map<String, String> map = Map.of("A","A","B","B","C","C");
        System.out.println(map);

Java 9 私有接口方法

Java 9 不仅像 Java 8 一样支持接口默认方法,同时还支持私有方法。

在 Java 9 中,一个接口中能定义如下几种变量/方法:

public interface MyInterface {

    void normalInterfaceMethod();

    default void interfaceMethodWithDefault() {  init(); }

    default void anotherDefaultMethod() { init(); }

    // This method is not part of the public API exposed by MyInterface
    private void init() { System.out.println("Initializing"); }
}

Java 9 改进的 Stream API

Java 9 改进的 Stream API 添加了一些便利的方法,使流处理更容易,并使用收集器编写复杂的查询。

Java 9 为 Stream 新增了几个方法:dropWhile、takeWhile、ofNullable,为iterate方法新增了一个重载方法。

takeWhile 方法

语法

default Stream<T> takeWhile(Predicate<? super T> predicate)

takeWhile() 方法使用一个断言作为参数,返回给定 Stream 的子集直到断言语句第一次返回 false。如果第一个值不满足断言条件,将返回一个空的 Stream。

takeWhile() 方法在有序的 Stream 中,takeWhile 返回从开头开始的尽量多的元素;在无序的 Stream 中,takeWhile 返回从开头开始的符合 Predicate 要求的元素的子集。

Stream.of("a","b","c","","e","f").takeWhile(s -> !s.isEmpty()).forEach(System.out::println);

以上实例 takeWhile 方法在碰到空字符串时停止循环输出,执行输出结果为:

a
b
c

dropWhile 方法

语法

default Stream<T> dropWhile(Predicate<? super T> predicate)

dropWhile 方法和 takeWhile 作用相反的,使用一个断言作为参数,直到断言语句第一次返回 false 才返回给定 Stream 的子集。

Stream.of("a","b","c","","e","f").dropWhile(s -> !s.isEmpty()).forEach(System.out::print);

以上实例 dropWhile 方法在碰到空字符串时开始循环输出,执行输出结果为:

e f

iterate 方法

语法

static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)

这个是用来生成有限流的新迭代实现。

举个例子:

Stream.iterate(0,i -> i<5,i -> i+1).forEach(System.out::print);

以上实例 iterate方法是从0开始,当5小于5,i+1

01234

ofNullable 方法

语法

static <T> Stream<T> ofNullable(T t)

ofNullable 方法可以预防 NullPointerExceptions 异常, 可以通过检查流来避免 null 值。

如果指定元素为非 null,则获取一个元素并生成单个元素流,元素为 null 则返回一个空流。

        long count = Stream.ofNullable(100).count();
        System.out.println(count);

        count = Stream.ofNullable(null).count();
        System.out.println(count);

Java 9 改进的 try-with-resources

在Java 7 中引入了try-with-resources功能,保证了每个声明了的资源在语句结束的时候都会被关闭。任何实现了java.lang.AutoCloseable接口的对象,和实现了java.io.Closeable接口的对象,都可以当做资源使用。

在Java 7中需要这样写:

        try (BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
             BufferedInputStream bufferedInputStream1 = new BufferedInputStream(System.in)) {
            System.out.println("do something");
        } catch (IOException e) {
            e.printStackTrace();
        }

而到了Java 9简化为:

        BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
        BufferedInputStream bufferedInputStream1 = new BufferedInputStream(System.in);

        try (bufferedInputStream;bufferedInputStream1) {
            System.out.println("do something");
        } catch (IOException e) {
            e.printStackTrace();
        }

Java 9 改进的 Optional 类

Optional 类在 Java 8 中引入,Optional 类的引入很好的解决空指针异常。。在 java 9 中, 添加了三个方法来改进它的功能:

stream() 方法

语法

public Stream<T> stream()

stream 方法的作用就是将 Optional 转为一个 Stream,如果该 Optional 中包含值,那么就返回包含这个值的 Stream,否则返回一个空的 Stream(Stream.empty())。

ifPresentOrElse() 方法

语法

public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

ifPresentOrElse 方法的改进就是有了 else,接受两个参数 Consumer 和 Runnable。

ifPresentOrElse 方法的用途是,如果一个 Optional 包含值,则对其包含的值调用函数 action,即 action.accept(value),这与 ifPresent 一致;与 ifPresent 方法的区别在于,ifPresentOrElse 还有第二个参数 emptyAction —— 如果 Optional 不包含值,那么 ifPresentOrElse 便会调用 emptyAction,即 emptyAction.run()。

or() 方法

语法

public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)

如果值存在,返回 Optional 指定的值,否则返回一个预设的值。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注