从Java8到Java15的所有内容都可以在10分钟内理解清楚

本文是根据Philipp Gysel先生的文章《在十分钟内从Java 8到Java 15》(发布于2021年1月18日)的翻译版本,并获得了作者的许可才进行发布。

从Java8到Java15,只需10分钟就能理解。

Image for post

从Java 8到Java 15的历程中,有许多好消息。

首先

本文介绍了自Java 7以来新增的出色新功能。从发布于2020年秋的Java 15开始,将逐个版本地看到Java的重大改进点。现在的Java已经完全支持Lambda表达式、函数式编程、通过var进行类型推断、通过简化的构造函数创建不可变集合以及多行字符串。此外,还引入了一些新颖有趣的实验性功能,如数据类(record)和sealed类。最后,将解释高效的Java REPL。

1. 函数式编程(Java 8)

Java 8添加了函数式编程和Lambda表达式作为语言功能。函数式编程的两个核心范式是不变的值和函数的重要性提升。数据通过转换处理的管道流转。它在每个步骤中接收输入,并将其映射到新的输出上。函数式编程可以在Java的Stream和空值安全的单子(Optional)中使用,如下所示。

2. 流(Java 8)

在一般的计算机程序中,经常需要操作值的列表,并对每个值执行所需的转换。在Java 8之前,需要使用for循环来执行这种转换,但从现在开始,可以使用Stream来实现。

Stream.of("hello", "great")
    .map(s -> s + " world")
    .forEach(System.out::println);
> hello world
> great world

Streams.java 可以被返述为流.java。

map函数接收一个lambda函数作为输入,并将其应用于流中的所有元素。

Stream可以在List、Set、Map上运作(通过转换)。有了Stream,可以几乎不需要循环代码!?

3. Java 8的可选项

在Java中经常遇到的另一个问题是空指针异常。因此,Java引入了Optional。这是一个包装引用的单子,可以处理空值和非空值的情况。要将其升级为Optional,可以使用函数的形式。

Optional.of(new Random().nextInt(10))
    .filter(i -> i % 2 == 0)
    .map(i -> "number is even: " + i)
    .ifPresent(System.out::println);
> number is even: 6

Optional.java 可选.java

在上面的例子中,我们创建了一个随机数,并用Optional对象进行包装,只有在偶数的情况下才输出值。

4. JShell(Java 9)

终于,这就是Java的REPL,JShell!?简单来说,通过使用JShell,您可以在不编译整个Java类的情况下尝试代码片段。只需执行一个命令,即可立即获取结果。以下是一个简单的示例。

$ <JDK>/bin/jshell
jshell> System.out.println("hello world")
hello world

JShell.sh 的中文释义是什么?

擅长JavaScript和Python等解释型语言的人们一直以来都能够享受REPL的乐趣,但是Java以前一直没有这样的功能。有了JShell,不仅可以定义变量,还可以定义更复杂的实体,例如多行函数、类和循环等。此外,JShell还支持自动补全,当不知道特定Java类提供的准确方法时非常方便。

5. 不变集合的工厂方法(Java 9)

在Java中,长时间缺少对List的简单初始化的支持,但这种时代已经结束了。?以前我们必须这样做。

jshell> List<Integer> list = Arrays.asList(1, 2, 3, 4)
list ==> [1, 2, 3, 4]

收集旧的.sh文件。

这被简化为以下形式。

jshell> List<Integer> list = List.of(1, 2, 3, 4)
b ==> [1, 2, 3, 4]

收藏新的.sh

这个很酷的(…)方法可以在List、Set和Map中找到。无论哪一个,都可以通过一行简单的代码创建不可变对象。

6. 基于var的类型推断 (Java 10)

在Java 10中引入了新的var关键字,可以省略变量的类型。

jshell> var x = new HashSet<String>()
x ==> []

jshell> x.add("apple")
$1 ==> true

TypeInference.sh 的原生汉语解释如下:推断类型.sh

在上面的例子中,编译器可以推断出变量x的类型是HashSet。

这个功能很方便,可以减少样板代码并提高可读性。但是它有一些限制。var只能在方法体内使用。编译器在编译时推断类型,所以所有的都是静态类型的。

7. 单个源文件的启动(Java 11)

在过去,如果要编写一个简单的Java程序,我们首先需要使用javac编译该文件,然后才能使用java命令来运行它。但在Java 11中,我们可以通过一个命令来同时执行这两个步骤。

首先,我们要定义一个名为Main.java的单一源文件。

public class Main {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

单一源码启动.java

现在,您可以一步完成编译和执行了。

$ java ./Main.java
hello world

单一源启动.sh

对于简单的入门程序或只有一个Java类的测试情况,使用这个功能可以更轻松地启动单个源代码文件。

8. 开关风格(Java 12)

在Java 12中,引入了Switch表达式。在这里,我将简要介绍这个表达式与旧的switch语句有何区别。

传统的switch语句定义了程序的流程。

jshell> var i = 3
jshell> String s;
jshell> switch(i) {
    ...>    case 1: s = "one"; break;
    ...>    case 2: s = "two"; break;
    ...>    case 3: s = "three"; break;
    ...>    default: s = "unknown number";
    ...> }
jshell> s
s ==> "three"

切换旧版本.sh

相比之下,新的Switch类型会返回一个值。

jshell> var i = 3;
jshell> var x = switch(i) {
    ...>    case 1 -> "one";
    ...>    case 2 -> "two";
    ...>    case 3 -> "three";
    ...>    default -> "unknown number";
    ...> };
x ==> "three"

切换新脚本.sh

请注意,这个新的switch表达式是一种映射函数。它有一个输入(在这里是i)和一个输出(在这里是x)。实际上,它是一种模式匹配功能,可以将Java更好地与函数式编程的原则兼容,并在一定时间内在Scala中也可以使用类似的switch语句。

有几个需要注意的要点。

    • コロンの代わりに、矢印->を使っています。

 

    • breakは必要ありません。

 

    • 考え得るすべてのcaseを考慮すれば、defaultは省略できます。

 

    Java 12でこの機能を有効にするには、–enable-preview -source 12を使用します。

9. 文本多行(Java 13)

你有定义过类似JSON或XML的长多行字符串吗?以前,我们常常将所有内容放在一行中,并使用换行符\n,但是这样会使得字符串难以阅读。从Java 13开始,我们可以使用多行字符串了!?

请告诉我你的名字。

public class Main {
    public static void main(String [] args) {
        var s = """
            {
                "recipe": "watermelon smoothie",
                "duration": "10 mins",
                "items": ["watermelon", "lemon", "parsley"]
            }""";
        System.out.println(s);
    }
}

多行字符串.java

现在让我们尝试以单个文件启动并执行Main方法。

java --enable-preview --source 13 Main.java
{
    "recipe": "watermelon smoothie",
    "duration": "10 mins",
    "items": ["watermelon", "lemon", "parsley"]
}

MultiLineString.sh 可以进行以下的多行字符串操作。

得到的字符串结果跨越多行,引号””保持不变,制表符\t也保留着!

10. Java 14中的数据类record。

在这篇文章中,我最激动的可能是这个新功能。Java终于引入了数据类!这个类通过record关键字声明,自动包含Getter、构造函数、equals方法等。简而言之,可以消除大量的样板代码!??

jshell> record Employee (String name, int age, String department) {}
| created record Employee

jshell> var x = new Employee("Anne", 25, "Legal");
x ==> Employee[name=Anne, age=25, department=Legal]

jshell> x.name()
$2 ==> "Anne"

录音.sh

Scala有一个类似的案例类,Kotlin有数据类。在Java中,许多开发者使用Lombok来提供Java 14的record所影响的大部分功能。请参阅Baeldung的文章以了解更多详细信息。

11. 没有cast的instanceof (Java 14)

instanceof 关键字在Java的早期版本中就已经存在了。

Object obj = new String("hello");
if (obj instanceof String) {
    System.out.println("String length: " + ((String)obj).length());
}

InstanceOfOld.java 的实例

遗憾的部分是,首先要确认 obj 是 String 类型,然后重新转换类型并获取其长度。

在Java 14中,编译器自动进行类型推断后进行了instanceof检查。

Object obj = new String("hello");
if (obj instanceof String mystr) {
    System.out.println("String length: " + mystr.length());
}

InstanceOfNew.java 的实例

12. 封闭类(Java 15)

使用sealed关键字,可以限制能够扩展指定类和接口的类。

请帮我翻译英文句子:“Can you help me with my homework?”

public sealed interface Fruit permits Apple, Pear {
    String getName();
}

public final class Apple implements Fruit {
    public String getName() { return "Apple"; }
}

public final class Pear implements Fruit {
    public String getName() { return "Pear"; }
}

封装类.java

这有什么用呢?你知道有多少水果了吧。这是朝着完全支持的模式匹配迈出的重要一步。可以像枚举类型一样处理类。这个sealed功能与前面介绍的新switch表达式非常相配。

附加信息:Java 8及以上版本的许可条款更新

这篇文章的最后一个话题是许可证。你有没有听说过Oracle停止更新Java 8(免费商业版本)的消息?因此,有以下选择。

    • 新しいOracle JDKバージョンを使用する(Oracleは各リリース後6ヶ月間だけ無料のセキュリティアップデートを提供)。

 

    • 自己責任で古いJDKバージョンを使用する。

 

    • 古いOpenJDKのJavaバージョンを使用する。これは引き続き、オープンソースコミュニティやサードパーティベンダーからセキュリティアップデートを取得する。

 

    プレミアムサポートのためOracleに支払う(例:Java 8は2030年までサポート)。

下一项是针对每个JDK的临时Oracle支持期限。

Image for post

每个JDK版本的Oracle支持计划

Oracle新的许可模式将受到新发布周期的影响。Oracle将每6个月发布一个新的Java版本。这样,Oracle可以更快地改进Java,并通过实验性功能获得更快的反馈,以跟上最新的语言,如Scala、Kotlin和Python。

请查阅此篇文章获取有关许可证的详细信息。

总结

在过去的6年里,Java经历了艰苦的旅程,并发布了8个全新的Java版本!?这些令人惊叹的新功能都有助于使Java成为与其他基于JVM的竞争对手(如Scala和Kotlin)相比具有竞争力的选择。

写这篇文章真的很开心? 谢谢你的阅读? 最近Java的新版本中,你最喜欢的功能是什么?期待听到你的想法!

在DEV.to首次公开发表。

合作翻译

本文得以公开,有赖以下人士的合作。再次表示感谢。

感谢您愿意与我们分享知识!

指定职责:@gracen
翻译职责:@gracen
审计职责:-
公开职责:@gracen

我們期待著您的意見和反饋。

请问这篇文章您觉得如何呢?
– 您希望看到这样的文章
– 您认为哪些地方不错
– 您认为应该这样做更好吗
等等,我们征求您真实的意见。
收到的意见将对提升今后文章的质量有所帮助,欢迎您在评论区留言,不用客气。
我们也接受意见反馈于Twitter上。
期待大家的留言。

广告
将在 10 秒后关闭
bannerAds