介绍
Oracle 在2017年3月左右发布Java新版本:Java SE9。陆续我会发表一系列有关Java SE 9新功能的文章。这是本系列的第三篇。
我已经发表了几篇有关Java SE 9新特性的文章。在阅读这篇文章之前,请先阅读以下文章:
在本文中,我会带着大家一起来讨论一下Java SE 9新功能:Immutable List的 工厂方,在讲解的过程中会穿插一些简单而合适的示例。
Java SE 8: 空的不可变列表
在Java SE 8和更早版本中,如果我们要创建一个空的不可变或不可修改的列表,则应该使用Collections类提供的静态方法:unmodifiableList(),如下所示:
List emptyList = new ArrayList<>();
List immutableList = Collections.unmodifiableList(emptyList);
注意:<> 操作符在Java SE 6和早期版本中不起作用,其余代码在所有Java版本中通用。
我们在REPL中测试上述代码:
➜ ~ jshell
| Welcome to JShell -- Version 11.0.5
| For an introduction type: /help intro
jshell> List emptyList = new ArrayList<>();
emptyList ==> []
jshell> List immutableList = Collections.unmodifiableList(emptyList);
immutableList ==> []
jshell>
正如上面操作的那样,创建一个空的不可变列表,我们需要做很多事情。一个简单的事情竟是如此的繁琐和冗长。现在让我们在Java SE 9中看看该如何操作。
注意:-为了简便和快速的验证功能,我使用Java SE 9 REPL(JShell)。这就是为什么需要各种语言使用REPL来快速测试新功能而无需做很多工作的原因,Java 也不例外。
Java SE 9: 空的不可变列表
为了克服这些缺点,Java SE 9在List接口中引入了两个有用的方法,因此我们不需要再使用如此繁琐的步骤来创建不可变的空列表了。
通过Java SE 9 List API,我们可以在List接口中找到以下方法签名。
static List of()
它用于创建一个空的不可变列表(具有零个元素的列表)。
List immutableList = List.of();
我们在在REPL中测试上述代码:
➜ ~ jshell
| Welcome to JShell -- Version 11.0.5
| For an introduction type: /help intro
jshell> List immutableList = List.of();
immutableList ==> []
jshell>
我们可以看到,在Java SE 9中创建一个空的不可变列表非常容易。
Java SE 8:非空不可变列表
现在,让我们来看看如何在Java SE 8和更早版本中创建非空不可变列表。
List list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
List immutableList = Collections.unmodifiableList(list);
在这里,我们还可以观察到,要创建一个非空的不可变列表,我们需要做很多事情以及非常繁琐和冗长的步骤。现在让我们在Java SE 9中看看做同样的事情该如何操作。
Java SE 9:非空不可变列表
为了克服上述的这些缺点,Java SE 9引入了以下几个重载方法。这些方法用于创建1-10个不等元素新的不可变列表。
static List of(E e1)
static List of(E e1,E e2)
static List of(E e1,E e2,E e3)
static List of(E e1,E e2,E e3,E e4)
static List of(E e1,E e2,E e3,E e4,E e5)
static List of(E e1,E e2,E e3,E e4,E e5,E e6)
static List of(E e1,E e2,E e3,E e4,E e5,E e6,E e7)
static List of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8)
static List of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8,E e9)
static List of(E e1,E e2,E e3,E e4,E e5,E e6,E e7,E e8,E e9,E e10)
以下是Var-Args方法(可变参数方法):
static List of(E... elements)
示例:
List immutableList = List.of("one","two","three");
哈哈,是不是非常简单~
我们在在REPL中测试上述代码:
jshell> List immutableList = List.of("one","two","three")
immutableList ==> [one, two, three]
不可变列表的特征
我们都知道,不可变列表是不可修改的。在本节中,我们将讨论不可变列表的一些基本特征(在所有Java版本中都一样):
它们是不可变的。
我们无法添加,修改和删除其内部的元素。
如果尝试对它们执行添加/删除/更新操作,则会得到UnsupportedOperationException,如下所示:
jshell> immutableList.add("four")
| java.lang.UnsupportedOperationException thrown:
| at ImmutableCollections.uoe (ImmutableCollections.java:68)
| at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:74)
| at (#2:1)
```
不允许有空元素(null)
如果试图使用null元素创建它们,则会抛出NullPointerException,如下所示:
jshell> List>String> immutableList = List.of("one","two","three", null)
| Error:
| cannot find symbol
| symbol: variable List
| List>String> immutableList = List.of("one","two","three", null)
| ^--^
| Error:
| cannot find symbol
| symbol: variable String
| List>String> immutableList = List.of("one","two","three", null)
| ^----^
jshell>
如果试图添加null元素,则会抛出UnsupportedOperationException,如下所示:
jshell> immutableList.add(null)
| Exception java.lang.UnsupportedOperationException
| at ImmutableCollections.uoe (ImmutableCollections.java:71)
| at ImmutableCollections$AbstractImmutableCollection.add (ImmutableCollections.java:75)
| at (#2:1)
jshell>
如果 List里面所有元素都是可序列化的,则它们是可序列化的。
就是Java SE 9:不可变列表的工厂方法的一些特性。我们将在以后的文章中讨论更多关于Java SE 9的新功能。