提交 8ec25e7c 编写于 作者: W wizardforcel

2021-09-21 21:49:24

上级 e71b356e
......@@ -216,7 +216,7 @@ Haskell 使用以下单子(在其他函数式编程语言中导入)。它们
* 写入器单子用于将状态附加到多个写入器,非常类似于记录到多个写入器(控制台/文件/网络)的日志过程。
* 状态单子既是读取器又是写入器。
为了掌握函子、应用和单子的概念,我们建议您查阅[这个页面](http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html)[这个页面](https://bartoszmilewski.com/2011/01/09/monads-for-the-curious-programmer-part-1/)。在[这个页面](https://github.com/aol/cyclops-react)剑水蚤反应图书馆里也有一些函数式的好东西。
为了掌握函子、应用和单子的概念,我们建议您查阅[这个页面](http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html)[这个页面](https://bartoszmilewski.com/2011/01/09/monads-for-the-curious-programmer-part-1/)。在[这个页面](https://github.com/aol/cyclops-react) Cyclops React 库里也有一些函数式的好东西。
# Java 函数式编程简介
......
......@@ -139,7 +139,7 @@ Java 的 MacOS 版本以`.dmg`文件的形式出现。这是 MacOS 的打包格
在 Linux 上安装 Java 有几种方法,这取决于它的风格。在这里,我将描述一种安装方法,它在所有风格上的工作方式或多或少都是相同的。我用的是 Debian。
第一步与在任何其他操作系统中下载安装工具包的步骤相同。在 Linux 中,您应该选择一个以`tar.gz`结尾的包。这是一种压缩的存档格式。您还应该仔细选择与计算机中的处理器和 32/64 位操作系统版本相匹配的软件包。软件包下载完成后,需要切换到 root 模式,发出`su`命令。这是您在以下屏幕截图中看到的第一个命令,显示了安装命令:
第一步与在任何其他操作系统中下载安装工具包的步骤相同。在 Linux 中,您应该选择一个以`tar.gz`结尾的包。这是一种压缩的存档格式。您还应该仔细选择与计算机中的处理器和 32/64 位操作系统版本相匹配的包。包下载完成后,需要切换到 root 模式,发出`su`命令。这是您在以下屏幕截图中看到的第一个命令,显示了安装命令:
![](img/06eb92d5-f573-49b0-9268-148cba25dc04.png)
......@@ -736,7 +736,7 @@ public class HelloWorldLoop {
}
```
程序包含一个`for`循环。循环允许重复执行代码块,我们将在第 2 章“第一个真正的 Java 程序——排序名称”讨论。我们在这里创建的循环是一个特殊的循环,它从不终止,而是重复打印方法调用,打印`Hello World`,直到在 Linux 或 MacOSX 上按`Ctrl + C`或发出`kill`命令终止程序,或者在 Windows 下的任务管理器中终止程序。
包含一个`for`循环。循环允许重复执行代码块,我们将在第 2 章“第一个真正的 Java 程序——排序名称”讨论。我们在这里创建的循环是一个特殊的循环,它从不终止,而是重复打印方法调用,打印`Hello World`,直到在 Linux 或 MacOSX 上按`Ctrl + C`或发出`kill`命令终止程序,或者在 Windows 下的任务管理器中终止程序。
在一个窗口中编译并启动它,然后打开另一个终端窗口来管理应用。
......
......@@ -321,7 +321,7 @@ Define value for property 'artifactId': : SortTutorial
Define value for property 'version': 1.0-SNAPSHOT: : 1.0.0-SNAPSHOT
```
语义版本控制,定义于[这个页面](http://semver.org/)是一种版本控制方案,建议*主要**次要**补丁*版本号使用三位版本号`M.M.p`。这对图书馆非常有用。如果自上一版本以来只有一个 bug 修复,那么您将增加最后一个版本号。当新版本还包含新功能,但库与以前的版本兼容时,您将增加次要数字;换句话说,任何使用旧版本的程序仍然可以使用新版本。当新版本与前一版本有显著差异时,主要版本号会增加。在应用的情况下,没有使用应用 API 的代码;因此,次要版本号没有那么重要。不过,这并没有什么坏处,而且事实证明,在应用中发出较小变化的信号通常是有用的。我们将在最后一章讨论如何对软件进行版本化。
语义版本控制,定义于[这个页面](http://semver.org/)是一种版本控制方案,建议*主要**次要**补丁*版本号使用三位版本号`M.M.p`。这对非常有用。如果自上一版本以来只有一个 bug 修复,那么您将增加最后一个版本号。当新版本还包含新功能,但库与以前的版本兼容时,您将增加次要数字;换句话说,任何使用旧版本的程序仍然可以使用新版本。当新版本与前一版本有显著差异时,主要版本号会增加。在应用的情况下,没有使用应用 API 的代码;因此,次要版本号没有那么重要。不过,这并没有什么坏处,而且事实证明,在应用中发出较小变化的信号通常是有用的。我们将在最后一章讨论如何对软件进行版本化。
Maven 将带有`-SNAPSHOT`后缀的版本处理为非发布版本。在开发代码时,我们将有许多版本的代码,所有版本都具有相同的快照版本号。另一方面,非快照版本号只能用于单个版本:
......@@ -804,7 +804,7 @@ Java 语言中有一些我们不使用的特性。当语言被创建时,这些
在上一节中我已经提到了内部类和嵌套类。现在,我们将更详细地了解它们。
此时,内部类和嵌套类的细节可能很难理解。如果你不完全理解这一节,不要感到羞愧。如果太难,请跳到下一节,阅读有关软件包的内容,稍后返回此处。嵌套类、内部类和本地类很少使用,尽管它们在 Java 中有自己的角色和用途。匿名类在 GUI 编程中非常流行,Swing 用户界面允许开发人员创建 JavaGUI 应用。有了 Java8 和 Lambda 特性,匿名类现在已经不那么重要了,而随着 JavaScript 和浏览器技术的出现,JavaGUI 变得不那么流行了。
此时,内部类和嵌套类的细节可能很难理解。如果你不完全理解这一节,不要感到羞愧。如果太难,请跳到下一节,阅读有关包的内容,稍后返回此处。嵌套类、内部类和本地类很少使用,尽管它们在 Java 中有自己的角色和用途。匿名类在 GUI 编程中非常流行,Swing 用户界面允许开发人员创建 JavaGUI 应用。有了 Java8 和 Lambda 特性,匿名类现在已经不那么重要了,而随着 JavaScript 和浏览器技术的出现,JavaGUI 变得不那么流行了。
当一个类单独在一个文件中定义时,它被称为顶级类。显然,在另一个类中的类不是顶级类。如果它们是在与字段(不是某个方法或另一个块的局部变量)相同级别的类中定义的,则它们是内部类或嵌套类。它们之间有两个区别。一种是嵌套类在其定义中将`static`关键字放在`class`关键字之前,而内部类则没有。
......@@ -846,7 +846,7 @@ package packt.java11.example.stringsort;
如果不指定包,则类将位于默认包中。除非在最简单的情况下您想尝试一些代码,否则不应使用此选项。在 Java11 中,您可以使用`jshell`来实现这个目的。因此,与以前版本的 Java 不同,现在的建议变得非常简单:不要将任何类放在默认包中。
包的名称是分层的。名字的各个部分用点隔开。使用包名有助于避免名称冲突。类的名称通常保持简短,将它们放入包中有助于程序的组织。类的全名包括类所在的包的名称。通常,我们会将这些类放入一个以某种方式相关的包中,并向程序的类似方面添加一些内容。例如,MVC 模式程序中的控制器保存在单个包中。包还可以帮助您避免类的名称冲突。但是,这只会将问题从类名冲突推到包名冲突。我们必须确保包的名称是唯一的,并且当我们的代码与任何其他库一起使用时不会引起任何问题。当开发一个应用时,我们只是不知道在以后的版本中将使用哪些库。为了防患于未然,惯例是根据一些互联网域名来命名软件包。当开发公司拥有域名`acmecompany.com`时,他们的软件通常在`com.acmecompany...`包下。这不是一个严格的语言要求。从右到左写域名,并将其用作包名,这只是一种惯例,但这在实践中证明是相当好的。有时,就像我在这本书中所做的,一个人可以偏离这一做法,所以你可以看到这条规则不是刻在石头上的。
包的名称是分层的。名字的各个部分用点隔开。使用包名有助于避免名称冲突。类的名称通常保持简短,将它们放入包中有助于程序的组织。类的全名包括类所在的包的名称。通常,我们会将这些类放入一个以某种方式相关的包中,并向程序的类似方面添加一些内容。例如,MVC 模式程序中的控制器保存在单个包中。包还可以帮助您避免类的名称冲突。但是,这只会将问题从类名冲突推到包名冲突。我们必须确保包的名称是唯一的,并且当我们的代码与任何其他库一起使用时不会引起任何问题。当开发一个应用时,我们只是不知道在以后的版本中将使用哪些库。为了防患于未然,惯例是根据一些互联网域名来命名包。当开发公司拥有域名`acmecompany.com`时,他们的软件通常在`com.acmecompany...`包下。这不是一个严格的语言要求。从右到左写域名,并将其用作包名,这只是一种惯例,但这在实践中证明是相当好的。有时,就像我在这本书中所做的,一个人可以偏离这一做法,所以你可以看到这条规则不是刻在石头上的。
当机器启动时,代码被编译成字节码,包就成为类的名称。因此,`Sort`类的全名是`packt.java11.example.stringsort.Sort`。使用另一个包中的类时,可以使用此全名或将该类导入到类中。同样,这是在语言层面。当 Java 变成字节码时,使用完全限定名或导入没有区别。
......
......@@ -181,7 +181,7 @@ $ tree
使用 Maven 编译代码时,代码使用的库可以从存储库中获得。当 Ant 被开发出来时,存储库的概念还没有被发明出来。当时,开发人员将库的版本复制到源代码结构中的文件夹中。通常,`lib`目录用于此目的。
这种方法有两个问题:一个是源代码存储库的大小。例如,如果 100 个不同的项目使用 JUnit,那么 JUnit 库的 JAR 文件被复制了 100 次。另一个问题是收集所有的图书馆。当一个库使用另一个库时,开发人员必须阅读该库的文档,这些文档描述了使用该库所需的其他库。这往往是过时和不准确的。这些库必须以同样的方式下载和安装。这既耗时又容易出错。当库丢失而开发人员没有注意到它时,错误就会在编译时出现。如果依赖关系只能在运行时检测到,那么 JVM 就无法加载类。
这种方法有两个问题:一个是源代码存储库的大小。例如,如果 100 个不同的项目使用 JUnit,那么 JUnit 库的 JAR 文件被复制了 100 次。另一个问题是收集所有的。当一个库使用另一个库时,开发人员必须阅读该库的文档,这些文档描述了使用该库所需的其他库。这往往是过时和不准确的。这些库必须以同样的方式下载和安装。这既耗时又容易出错。当库丢失而开发人员没有注意到它时,错误就会在编译时出现。如果依赖关系只能在运行时检测到,那么 JVM 就无法加载类。
为了解决这个问题,Maven 提供了一个内置的仓库管理器客户端。存储库是包含库的存储。由于存储库中可能有其他类型的文件,而不仅仅是库,Maven 术语是*工件*`groupId``artifactId``version`数字标识伪影。有一个非常严格的要求,工件只能放入存储库一次。即使在发布过程中有一个错误在错误的发布被上传后被识别,工件也不能被覆盖。对于相同的`groupId``artifactId``version`,只能有一个永远不会更改的文件。如果存在错误,则使用新版本号创建一个新工件,并且可以删除错误工件,但永远不会替换。
......@@ -373,7 +373,7 @@ public interface Sortable {
另外一个有趣的性能问题是,如何通过只使用`List`接口的搜索来实现两个元素的交换。`List`接口中没有`put(int, Object)`方法。有`add(int, Object)`,但它插入了一个新元素,如果对象存储在磁盘上,那么将列表中的所有元素向上推可能会非常昂贵(消耗 CPU、磁盘、能量)。此外,下一步可能是删除我们刚刚插入的元素之后的元素,再次移动列表尾部的代价高昂。这就是`put(int, Object)`的琐碎实现。排序可能跟在后面,也可能跟不上。同样,这是不应该假设的。
当您使用来自 JDK、开源或商业库的库、类和方法时,您可以参考源代码,但不应依赖于实现。您应该只依赖于该库附带的 API 的契约和定义。当您从某个外部库实现一个接口时,您不需要实现它的某些部分,也不需要创建一些虚拟方法,您会感到危险。这是埋伏。很可能是图书馆质量不好,或者你不知道如何使用它。我不知道哪个更糟。
当您使用来自 JDK、开源或商业库的库、类和方法时,您可以参考源代码,但不应依赖于实现。您应该只依赖于该库附带的 API 的契约和定义。当您从某个外部库实现一个接口时,您不需要实现它的某些部分,也不需要创建一些虚拟方法,您会感到危险。这是埋伏。很可能是质量不好,或者你不知道如何使用它。我不知道哪个更糟。
在我们的例子中,我们将交换和比较与排序分开。集合应该实现这些操作并为排序提供它们。契约就是接口,要使用排序,必须实现我们定义的接口的所有方法。
......@@ -1023,7 +1023,7 @@ public class Partitioner<E> {
这段代码什么也不做,但 TDD 就是这样开始的。我们将创建需求的定义,提供代码的框架和调用它的测试。要做到这一点,我们需要一些我们可以分割的东西。最简单的选择是一个`Integer`数组。`partition`方法需要一个`Sortable<E>`类型的对象,我们需要一些包装数组并实现这个接口的东西。我们把那个类命名为`ArrayWrapper`。这是一个通用类。这不仅仅是为了考试。因此,我们将其创建为生产代码,因此,我们将其放在`main`目录中,而不是`test`目录中。因为这个包装器独立于`Sort`的实现,所以这个类的正确位置是在一个新的`SortSupportClasses`模块中。我们将创建新模块,因为它不是接口的一部分。实现依赖于接口,而不依赖于支持类。也可能有一些应用使用我们的库,可能需要接口模块和一些实现,但当它们自己提供包装功能时仍然不需要支持类。毕竟,我们不能实现所有可能的包装功能。SRP 也适用于模块。
Java 库往往包含不相关的功能实现。这不好。就短期而言,它使图书馆的使用更简单。您只需要在 POM 文件中指定一个依赖项,就可以拥有所需的所有类和 API。从长远来看,应用变得越来越大,携带了许多属于某些库的类,但应用从不使用它们。
Java 库往往包含不相关的功能实现。这不好。就短期而言,它使的使用更简单。您只需要在 POM 文件中指定一个依赖项,就可以拥有所需的所有类和 API。从长远来看,应用变得越来越大,携带了许多属于某些库的类,但应用从不使用它们。
要添加新模块,必须创建模块目录以及源目录和 POM 文件。该模块必须添加到父 POM 中,并且还必须添加到`dependencyManagement`部分,以便`QuickSort`模块的测试代码可以使用它而不指定版本。新模块依赖于接口模块,因此必须将此依赖关系添加到支持类的 POM 中。
......
......@@ -637,7 +637,7 @@ public void setMatch(int matchedPositions, int matchedColors) {
}
```
`setMatch`方法不仅设置值,而且检查值是否一致。两个值之和不能超过列数。此检查确保使用`Row`类 API 的调用方不会不一致地使用它。如果这个 API 只在我们的代码中使用,那么这个断言不应该是代码的一部分。在这种情况下,良好的编码风格将确保使用单元测试时不会不一致地调用该方法。当我们在无法控制的情况下创建要使用的 API 时,我们应该检查使用是否一致。如果不这样做,我们的代码在不一致地使用时可能会表现得很奇怪。当调用者将匹配设置为与任何可能的猜测都不匹配的值时,游戏可能永远不会结束,调用者可能很难弄清楚到底发生了什么。这可能需要我们代码的调试执行。这不是图书馆用户的任务。始终尝试创建不需要从 API 使用者处调试的代码。
`setMatch`方法不仅设置值,而且检查值是否一致。两个值之和不能超过列数。此检查确保使用`Row`类 API 的调用方不会不一致地使用它。如果这个 API 只在我们的代码中使用,那么这个断言不应该是代码的一部分。在这种情况下,良好的编码风格将确保使用单元测试时不会不一致地调用该方法。当我们在无法控制的情况下创建要使用的 API 时,我们应该检查使用是否一致。如果不这样做,我们的代码在不一致地使用时可能会表现得很奇怪。当调用者将匹配设置为与任何可能的猜测都不匹配的值时,游戏可能永远不会结束,调用者可能很难弄清楚到底发生了什么。这可能需要我们代码的调试执行。这不是用户的任务。始终尝试创建不需要从 API 使用者处调试的代码。
如果我们在这种情况下抛出异常,程序将在错误所在的位置停止。不需要调试库。
......
......@@ -57,7 +57,7 @@
在本节中,我们将设计要实现的两个接口。在设计接口时,我们首先关注功能。格式和协议稍后提供。接口,一般来说,应该是简单的,同时,适应未来的变化。这是一个困难的问题,因为我们看不到未来。商业、物流和所有其他专家可能会看到未来世界的某些部分将如何变化,以及它将对公司的运营,特别是我们为合作伙伴提供的接口带来什么影响。
接口的稳定性是最重要的,因为合作伙伴是外部实体。我们无法重构它们使用的代码。当我们在代码中更改 Java 接口时,编译器将在所有应该遵循更改的代码位置抱怨。如果是在我们的领域之外使用的接口,情况并非如此。即使我们在 *GitHub* 上发布为开源的 Java 接口,我们也应该做好准备,如果我们以不兼容的方式更改库,用户也会面临问题。在这种情况下,他们的软件将不会编译和与我们的图书馆一起工作。如果是订购系统,这意味着他们不会从我们那里订购,我们很快就会倒闭。
接口的稳定性是最重要的,因为合作伙伴是外部实体。我们无法重构它们使用的代码。当我们在代码中更改 Java 接口时,编译器将在所有应该遵循更改的代码位置抱怨。如果是在我们的领域之外使用的接口,情况并非如此。即使我们在 *GitHub* 上发布为开源的 Java 接口,我们也应该做好准备,如果我们以不兼容的方式更改库,用户也会面临问题。在这种情况下,他们的软件将不会编译和与我们的一起工作。如果是订购系统,这意味着他们不会从我们那里订购,我们很快就会倒闭。
这就是为什么接口应该简单的原因之一。虽然这通常适用于生活中的大多数事情,但对于接口来说却是极其重要的。为合作伙伴提供方便的特性是很有诱惑力的,因为它们易于实现。但是,从长远来看,这些特性可能会变得非常昂贵,因为它们需要维护;它们应该保持向后兼容。从长远来看,他们可能得不到成本那么多。
......
......@@ -907,7 +907,7 @@ Git 在这个方向上走得很远。它非常支持分支创建和合并,以
# 选择库
为企业编程,甚至为中等规模的项目编程,都离不开外部库的使用。在 Java 世界中,我们使用的大多数库都是开源的,而且或多或少是免费的。当我们购买图书馆时,通常有一个由采购部门执行的标准流程。在这种情况下,有一个关于如何选择供应商和库的书面策略。在“自由”软件的情况下,他们通常不关心,尽管他们应该关心。在这种情况下,选择过程主要取决于 IT 部门,因此,在选择图书馆之前,即使图书馆是免费的,也要知道要考虑的要点。
为企业编程,甚至为中等规模的项目编程,都离不开外部库的使用。在 Java 世界中,我们使用的大多数库都是开源的,而且或多或少是免费的。当我们购买库时,通常有一个由采购部门执行的标准流程。在这种情况下,有一个关于如何选择供应商和库的书面策略。在“自由”软件的情况下,他们通常不关心,尽管他们应该关心。在这种情况下,选择过程主要取决于 IT 部门,因此,在选择库之前,即使库是免费的,也要知道要考虑的要点。
在上一段中,我把“免费”放在引号之间。这是因为没有软件是真正免费的。没有什么像他们说的那样是免费的午餐。您已经听过很多次了,但是对于您将要选择的开放源代码库或框架来说,这可能并不明显。任何购买或实现的主要选择因素是成本、价格。如果软件是免费的,这意味着你不需要为软件支付预付费。然而,集成和使用它是有成本的。支持要花钱。有人可能会说,这种支持是社区支持,也是免费的。问题是,你花在寻找一个能帮助你克服错误的变通方法上的时间仍然是金钱。这是你的时间,或者如果你是一个经理,这是你所在部门的专业人员的时间,你为他们的时间买单,或者,如果你没有解决问题的内部专业知识,外部承包商会给你一大笔账单。
......@@ -915,7 +915,7 @@ Git 在这个方向上走得很远。它非常支持分支创建和合并,以
# 适合目的
这也许是最重要的因素。其他因素可能会因重要性的大小而引起争论,但如果一个图书馆不适合我们的目的,那么不管怎样,这肯定不是可以选择的。在许多情况下,这可能是显而易见的,但您可能会惊讶地发现,有多少次我看到一个产品被选中,因为它是其他项目中某个人的最爱,而且该库被迫用于新项目中,尽管要求完全不同。
这也许是最重要的因素。其他因素可能会因重要性的大小而引起争论,但如果一个不适合我们的目的,那么不管怎样,这肯定不是可以选择的。在许多情况下,这可能是显而易见的,但您可能会惊讶地发现,有多少次我看到一个产品被选中,因为它是其他项目中某个人的最爱,而且该库被迫用于新项目中,尽管要求完全不同。
# 许可证
......@@ -935,7 +935,7 @@ Git 在这个方向上走得很远。它非常支持分支创建和合并,以
作为软件专业人士,我们能做些什么?
我们必须使用知名度高、用途广泛的图书馆。我们可以检查库的源代码,看看是否有复制的代码。一些包名可能提供线索。你可以用谷歌搜索部分源代码来找到匹配的。最后但同样重要的是,该公司可以订阅为图书馆提供类似研究的服务。
我们必须使用知名度高、用途广泛的库。我们可以检查库的源代码,看看是否有复制的代码。一些包名可能提供线索。你可以用谷歌搜索部分源代码来找到匹配的。最后但同样重要的是,该公司可以订阅为库提供类似研究的服务。
# 文档
......@@ -945,11 +945,11 @@ Git 在这个方向上走得很远。它非常支持分支创建和合并,以
# 有活力的项目
重要的是不要选择一个不存在的库来使用。请查看库的路线图、上一次发布版本的时间以及提交的频率。如果图书馆不存在,我们应该考虑不使用它。图书馆在一个环境中工作,环境也在变化。库可以连接到数据库。新版本的数据库可能会提供新的特性,只有在库被修改以适应这些新特性的情况下,才能提供更好的性能。该库通过 HTTP 进行通信;它是否支持新的 2.0 版本的协议?如果没有其他变化的话,Java 环境的版本会随着时间的推移而改变,我们使用的库迟早会跟随它来利用新特性。
重要的是不要选择一个不存在的库来使用。请查看库的路线图、上一次发布版本的时间以及提交的频率。如果库不存在,我们应该考虑不使用它。库在一个环境中工作,环境也在变化。库可以连接到数据库。新版本的数据库可能会提供新的特性,只有在库被修改以适应这些新特性的情况下,才能提供更好的性能。该库通过 HTTP 进行通信;它是否支持新的 2.0 版本的协议?如果没有其他变化的话,Java 环境的版本会随着时间的推移而改变,我们使用的库迟早会跟随它来利用新特性。
不能保证一个活着的图书馆永远活着。然而,一个已经死了的图书馆肯定不会复活。
不能保证一个活着的库永远活着。然而,一个已经死了的库肯定不会复活。
即使这个项目目前还活着,也有一些要点可能会给图书馆的未来带来一些提示。如果开发它的公司是成熟的,财务稳定,并且图书馆是以合理的商业模式开发的,那么项目死亡的风险就很低。如果有很多公司使用这个库,那么即使原来的团队停止工作或者原来的融资结构发生变化,这个项目也很可能继续存在。然而,这些只是小因素,并不是确凿的事实。没有保证,告诉未来更像是一门艺术而不是一门科学。
即使这个项目目前还活着,也有一些要点可能会给库的未来带来一些提示。如果开发它的公司是成熟的,财务稳定,并且库是以合理的商业模式开发的,那么项目死亡的风险就很低。如果有很多公司使用这个库,那么即使原来的团队停止工作或者原来的融资结构发生变化,这个项目也很可能继续存在。然而,这些只是小因素,并不是确凿的事实。没有保证,告诉未来更像是一门艺术而不是一门科学。
# 成熟度
......@@ -963,9 +963,9 @@ Git 在这个方向上走得很远。它非常支持分支创建和合并,以
# 用户数
如果图书馆是活的、成熟的,但用户不多,那就错了。如果图书馆好的话,人们为什么不用呢?如果一个库或框架的用户数量很低,并且用户中没有大公司,那么它可能不是一个好的库或框架。如果没有人使用它,这可能表明我们对其他标准的评估可能不合适。
如果库是活的、成熟的,但用户不多,那就错了。如果库好的话,人们为什么不用呢?如果一个库或框架的用户数量很低,并且用户中没有大公司,那么它可能不是一个好的库或框架。如果没有人使用它,这可能表明我们对其他标准的评估可能不合适。
还要注意的是,如果图书馆只有少数用户,社区的知识也很匮乏,我们可能无法得到社区的支持。
还要注意的是,如果只有少数用户,社区的知识也很匮乏,我们可能无法得到社区的支持。
# “我喜欢”的因素
......@@ -983,7 +983,7 @@ CI 服务器具有可用于创建版本的 Web 界面。在这种情况下,根
也可能会发生这样的情况:一个新的库被添加到构建的依赖项中,并且将它添加到构建文件(`pom.xml``build.gradle`中的开发人员可以在本地机器上毫无问题地使用它。这并不意味着该库已正式添加到项目中,而且它可能在中央代码库(Artifactory、Nexus 或代码库的其他实现)中不可用。这个库可能只存在于开发人员的本地存储库中,而且他们可能认为既然代码已经编译,构建就可以了。
一些大型组织对不同的项目使用不同的代码库。图书馆在经过仔细的检查和决定后进入这些资料库。有些图书馆可能到达那里,而另一些图书馆可能无法到达。拥有不同存储库的原因可能有很多。一个项目是为对一个开源项目有不同政策的客户开发的。如果企业为自己开发代码,可能会出现库被淘汰或不再受支持的情况,并且只能用于旧的项目。维护版本可能不需要替换库,但新项目可能不允许使用正在消亡的软件库。
一些大型组织对不同的项目使用不同的代码库。库在经过仔细的检查和决定后进入这些资料库。有些库可能到达那里,而另一些库可能无法到达。拥有不同存储库的原因可能有很多。一个项目是为对一个开源项目有不同政策的客户开发的。如果企业为自己开发代码,可能会出现库被淘汰或不再受支持的情况,并且只能用于旧的项目。维护版本可能不需要替换库,但新项目可能不允许使用正在消亡的软件库。
CI 服务器可以在一台计算机上运行,也可以在多台计算机上运行。如果它服务于许多项目,那么可以将它设置为一个中央服务器,其中有许多代理在不同的机器上运行。当必须启动构建过程时,中央服务器将此任务委托给其中一个代理。代理可能有不同的负载,运行几个不同的构建进程,并且可能有不同的硬件配置。构建过程可能对处理器的速度或可用内存有要求。有些代理可能会为较小的项目运行更简单的构建,但无法执行大型项目的构建,或者执行某些测试仍需要大量内存的小型项目的构建。
......
......@@ -37,7 +37,7 @@ JCL 是实现该语言的包的集合。更简单地说,它是 JDK 中包含
# `java.lang`
这个软件包非常重要,使用它不需要进口。JVM 作者决定自动导入它。它包含最常用的 JCL 类:
这个包非常重要,使用它不需要导入。JVM 作者决定自动导入它。它包含最常用的 JCL 类:
* `Object`类:其他 Java 类的基类
* `Class`类:在运行时携带每个加载类的元数据
......@@ -374,7 +374,7 @@ Apache Commons 项目包括以下三个部分:
* **Commons Proper**:可重用的 Java 组件,组成实际的`org.apache.commons`
我们讨论了第 5 章中的`org.apache.commons.io`包、“字符串、输入/输出和文件”。
在下面的小节中,我们将只讨论三个最受欢迎的通用软件包:
在下面的小节中,我们将只讨论三个最受欢迎的通用包:
* `org.apache.commons.lang3`
* `org.apache.commons.collections4`
......@@ -495,7 +495,7 @@ System.out.println(decodedStr); //prints: Hello, World!
# 总结
在本章中,我们概述了 JCL 最流行的软件包的功能:`java.lang``java.util``java.time``java.io``java.nio``java.sql``javax.sql``java.net``java.lang.math``java.math``java.awt``javax.swing``javafx`
在本章中,我们概述了 JCL 最流行的包的功能:`java.lang``java.util``java.time``java.io``java.nio``java.sql``javax.sql``java.net``java.lang.math``java.math``java.awt``javax.swing``javafx`
最流行的外部库是由`org.junit``org.mockito``org.apache.log4j``org.slf4j``org.apache.commons`包表示的,当这些功能已经存在并且可以直接导入和使用时,它可以帮助读者避免编写自定义代码。
......
......@@ -559,7 +559,7 @@ static class PostHandler implements HttpHandler {
这意味着客户端从服务器接收到消息并按预期退出。注意,我们示例中的服务器不会自动退出,必须手动关闭。
`URL``URLConnection`类的其他方法允许您设置/获取其他属性,并且可以用于客户端-服务器通信的更动态的管理。在`java.net`包中还有`HttpUrlConnection`类(以及其他类),它简化并增强了基于 URL 的通信。您可以阅读`java.net`软件包的在线文档,以便更好地了解可用的选项。
`URL``URLConnection`类的其他方法允许您设置/获取其他属性,并且可以用于客户端-服务器通信的更动态的管理。在`java.net`包中还有`HttpUrlConnection`类(以及其他类),它简化并增强了基于 URL 的通信。您可以阅读`java.net`包的在线文档,以便更好地了解可用的选项。
# 使用 HTTP 2 客户端 API
......
......@@ -111,7 +111,7 @@ java --module-path C:\path\JavaFX\lib --add-modules=javafx.controls,javafx.fxml
# 你好,JavaFX
下面是显示文本 HelloWorld 的`HelloWorld`JavaFX 应用!和出口
下面是显示文本 HelloWorld 的`HelloWorld`JavaFX 应用:
```java
import javafx.application.Application;
......@@ -150,7 +150,7 @@ public class HelloWorld extends Application {
}
```
如您所见,应用是通过调用静态方法`Application.launch(String... args)`来启动的。`start(Stage primaryStage)`方法创建一个`Text`节点,消息是 HelloWorld 位于绝对位置 135(水平)和 40(垂直)。然后创建另一个节点`Button`,文本出口位于 155(水平)和 80(垂直)的绝对位置。分配给按钮的操作(单击时)将打印“GoodBye”,并强制应用使用`Platform.exit()`方法退出。这两个节点作为子节点添加到允许绝对定位的布局窗格中
如您所见,应用是通过调用静态方法`Application.launch(String... args)`来启动的。`start(Stage primaryStage)`方法创建一个`Text`节点,消息是 HelloWorld 位于绝对位置 135(水平)和 40(垂直)。然后创建另一个节点`Button`,退出文本位于 155(水平)和 80(垂直)的绝对位置。分配给按钮的操作(单击时)将打印“GoodBye”,并强制应用使用`Platform.exit()`方法退出。这两个节点作为子节点添加到允许绝对定位的布局窗格中
`Stage`对象指定了主阶段(顶级容器)标题。它还指定了单击窗口上角的关闭窗口符号(x 按钮)的操作。此符号在 Linux 系统上显示在左侧,在 Windows 系统上显示在右侧
......
......@@ -81,7 +81,7 @@ primaryStage.onCloseRequestProperty()
所有这些例子都很好地说明了如何构造器并将其作为参数传递。这种能力构成了函数式编程。它存在于许多编程语言中。它不需要管理对象状态。函数是无状态的。它的结果只取决于输入数据,不管调用了多少次。这样的编码使得结果更加可预测,这是函数式编程最吸引人的方面。
从这种设计中受益最大的领域是并行数据处理。函数式编程允许将并行性的责任从客户端代码转移到库中。在此之前,为了处理 Java 集合的元素,客户端代码必须遍历集合并组织处理。在 Java8 中,添加了新的(默认)方法,这些方法接受一个函数作为参数,然后根据内部处理算法将其并行或不并行地应用于集合的每个元素。因此,组织并行处理是图书馆的责任。
从这种设计中受益最大的领域是并行数据处理。函数式编程允许将并行性的责任从客户端代码转移到库中。在此之前,为了处理 Java 集合的元素,客户端代码必须遍历集合并组织处理。在 Java8 中,添加了新的(默认)方法,这些方法接受一个函数作为参数,然后根据内部处理算法将其并行或不并行地应用于集合的每个元素。因此,组织并行处理是的责任。
# 什么是函数式接口?
......
......@@ -411,7 +411,7 @@ System.out.println(p2.getAddress().getStreet()); //prints: 25 Main Street
# 使用库
在整本书中,我们多次提到使用 **Java 类库****JCL**)、**Java 开发工具包****JDK**)和外部 Java 库可以使编程变得更简单,并生成更高质量的代码。甚至还有一个专门的章节,第 7 章、“Java 标准和外部库”,其中概述了最流行的 Java 库。创建图书馆的人会投入大量的时间和精力,所以你应该随时利用他们。
在整本书中,我们多次提到使用 **Java 类库****JCL**)、**Java 开发工具包****JDK**)和外部 Java 库可以使编程变得更简单,并生成更高质量的代码。甚至还有一个专门的章节,第 7 章、“Java 标准和外部库”,其中概述了最流行的 Java 库。创建的人会投入大量的时间和精力,所以你应该随时利用他们。
在第 13 章、“函数式编程”中,我们描述了驻留在 JCL 的`java.util.function`包中的标准函数式接口。这是另一种利用库的方法,使用一组众所周知的共享接口,而不是定义自己的接口。
......
......@@ -13,7 +13,7 @@
本章及后续章节主要介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
一个**集成开发环境****IDE**软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
一个**集成开发环境****IDE**)包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# 了解 Java 平台的新版本控制模型
......
......@@ -42,7 +42,7 @@ JEP 计划是 Oracle 支持开源、开放创新和开放标准的一部分。
本章及后续章节以 Java11 为特色,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站的链接](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
一个**集成开发环境****IDE**软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
一个**集成开发环境****IDE**)包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition)上找到。
......@@ -351,7 +351,7 @@ java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=ch2.jsa -cp ch2.jar Chapter
# 为模块化准备 JavaFXUI 控件和级联样式表 API
JavaFX 是一组允许设计和开发富媒体图形用户界面的软件包。JavaFX 应用为开发人员提供了一个很好的 API,用于为应用创建一致的接口。**级联样式表****CSS**)可用于定制接口。JavaFX 的一个优点是编程和接口设计的任务可以很容易地分开。
JavaFX 是一组允许设计和开发富媒体图形用户界面的包。JavaFX 应用为开发人员提供了一个很好的 API,用于为应用创建一致的接口。**级联样式表****CSS**)可用于定制接口。JavaFX 的一个优点是编程和接口设计的任务可以很容易地分开。
# JavaFX 概述
......
......@@ -21,7 +21,7 @@
本章及后续章节主要介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......
......@@ -18,7 +18,7 @@
本章及后续章节主要介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# 模块化入门
......
......@@ -17,7 +17,7 @@
本章及后续章节介绍 Java11。Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
一个**集成开发环境****IDE**软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
一个**集成开发环境****IDE**)包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......@@ -583,7 +583,7 @@ public class DependencyTest {
# `--add-opens`选项
您可以使用`--add-opens`运行时选项来允许您的代码访问非公共成员。这可以称为**深反射**。进行这种深度反思的图书馆能够访问所有成员,包括私有和公共。要授予这种类型的代码访问权限,可以使用`--add-opens`选项。语法如下:
您可以使用`--add-opens`运行时选项来允许您的代码访问非公共成员。这可以称为**深反射**。进行这种深度反射的库能够访问所有成员,包括私有和公共。要授予这种类型的代码访问权限,可以使用`--add-opens`选项。语法如下:
```java
--add-opens <module>/<package>=<target-module>(,<target-module>)*
......
......@@ -15,7 +15,7 @@
本章以 Java11 为特色,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......
......@@ -15,7 +15,7 @@
本章主要介绍 Java11。Java 平台的标准版(SE)可以从 [Oracle 的官方下载站点](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
[本章源代码可在 GitHub 上获取](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition)
......
......@@ -15,7 +15,7 @@
本章以 Java11 为特色,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......
......@@ -14,7 +14,7 @@
本章以 Java11 为特色,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......
......@@ -16,7 +16,7 @@
本章以及随后的章节以 Java18.9(也称为 Java11)为特色。Java 平台的标准版(SE)可以从 [Oracle 的官方下载站点](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
集成开发环境(IDE)软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。[IntelliJ IDEA 的社区版可从以下网站下载](https://www.jetbrains.com/idea/features/)
集成开发环境(IDE)包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。[IntelliJ IDEA 的社区版可从以下网站下载](https://www.jetbrains.com/idea/features/)
# Java 栈概述
......@@ -121,7 +121,7 @@ public class CheckEligibility {
一开始,这个参数设置似乎很复杂,很难理解。更合乎逻辑的做法是返回提供`StackFrame`对象的`Stream`,而不是强制调用者定义一个将其作为参数的函数。
示例代码使用 Lambda 表达式将函数定义为`walk()`方法的参数。Lambda 表达式的参数是流。因为这个流的第一个元素是实际的调用,所以我们放弃它。因为如果调用方不符合条件,也应该拒绝这些调用,即使对`hello()`方法的调用是通过库中已经存在的其他类和方法进行的,所以我们从框架中删除属于`CheckEligibility`类包中类的所有元素。这个包是`packt.java9.deep.stackwalker.myrestrictivelibrary`,在代码中,这个字符串存储在`packageName`字段中。结果流只包含来自库外部的`StackFrame`对象。我们把这些也扔下去,直到流耗尽,或者直到我们发现`StackFrame`又属于图书馆。如果所有的元素都消失了,我们就好了。在这种情况下,`count()`的结果为零。如果我们在`StackFrame`中找到一个属于库的类,这意味着外部代码是从库中调用的,在这种情况下,我们必须拒绝工作。在这种情况下,变量`eligible`将是`false`,我们抛出一个异常,如下面的屏幕截图所示:
示例代码使用 Lambda 表达式将函数定义为`walk()`方法的参数。Lambda 表达式的参数是流。因为这个流的第一个元素是实际的调用,所以我们放弃它。因为如果调用方不符合条件,也应该拒绝这些调用,即使对`hello()`方法的调用是通过库中已经存在的其他类和方法进行的,所以我们从框架中删除属于`CheckEligibility`类包中类的所有元素。这个包是`packt.java9.deep.stackwalker.myrestrictivelibrary`,在代码中,这个字符串存储在`packageName`字段中。结果流只包含来自库外部的`StackFrame`对象。我们把这些也扔下去,直到流耗尽,或者直到我们发现`StackFrame`又属于。如果所有的元素都消失了,我们就好了。在这种情况下,`count()`的结果为零。如果我们在`StackFrame`中找到一个属于库的类,这意味着外部代码是从库中调用的,在这种情况下,我们必须拒绝工作。在这种情况下,变量`eligible`将是`false`,我们抛出一个异常,如下面的屏幕截图所示:
![](img/8da943bd-0406-4257-8bcb-2707259cb2a4.png)
......
......@@ -25,7 +25,7 @@
本章介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
本章的源代码可以在 [GitHub 的 URL](https://github.com/PacktPublishing/Mastering-Java-11-Second-Edition) 上找到。
......@@ -220,7 +220,7 @@ Java9 DocletAPI 之前的版本,或者`com.sun.javadoc`包,使我们能够
为了调用 Javadoc,我们需要传递以下信息:
* 程序包名称
* 包名称
* 源文件名(用于类和接口)
* 访问控制选项可以是以下选项之一:
* `package`
......@@ -698,7 +698,7 @@ Javadoc 目录树
通过新的 Javadoc 搜索功能,我们可以搜索以下索引组件:
* 模块名称
* 程序包名称
* 包名称
* 类型
* 成员
* 使用新的`@index`内联标签索引的术语/短语
......@@ -1370,7 +1370,7 @@ MacOSX`com.apple.eawt`包是一个内部 API,从 Java9 开始,就不能再
新 API 已添加到`java.awt.Desktop`类中,并提供以下内容:
* 它创建了一个公共 API 来替换`com.apple.{east,eio}`中的功能。
* 它确保了 OSX 开发人员不会丢失功能。为此,当前的 Java 平台替换了以下软件包:
* 它确保了 OSX 开发人员不会丢失功能。为此,当前的 Java 平台替换了以下包:
* `com.apple.eawt`
* `com.apple.eio`
......
......@@ -15,7 +15,7 @@
本章以及随后的几章介绍 Java11。Java 平台的 SE 可从 [Oracle 官方网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
集成开发环境(IDE)软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
集成开发环境(IDE)包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# 反应式程序设计
......
......@@ -18,7 +18,7 @@
本章和随后的几章主要介绍 Java11。Java 平台的**标准版****SE**)可从 [Oracle 官网](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# 数据报传输层安全
......@@ -511,7 +511,7 @@ TLS 握手的五个步骤
`java.net.ssl`包包含与安全套接字包相关的类。这允许我们以 SSL 为例,可靠地检测引入网络字节流的错误。它还提供了加密数据以及提供客户端和服务器认证的能力。
软件包包括以下接口:
此包包括以下接口:
* `public interface HandshakeCompletedListener extends EventListener`
* `public interface HostnameVerifier`
......
......@@ -17,7 +17,7 @@
本章及后续章节主要介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# 统一 JVM 日志记录
......
......@@ -14,7 +14,7 @@
本章及后续章节主要介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# UTF-8 支持
......
......@@ -16,7 +16,7 @@
本章及后续章节主要介绍 Java11。Java 平台的**标准版****SE**)可从 [Oracle 官方下载网站](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章和后续章节相关的所有编码。IntelliJ IDEA 的社区版可从[网站](https://www.jetbrains.com/idea/features/)下载。
# JDK 增强提案概述
......
......@@ -14,7 +14,7 @@ Java 平台未来的关键是 Java 社区。这是本章的重点。我们将讨
本章介绍 Java11,Java 平台的**标准版****SE**)可从 [Oracle 官网](http://www.oracle.com/technetwork/java/javase/downloads/index.html)下载。
IDE 软件包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章相关的所有编码。[IntelliJ IDEA 的社区版可从以下网站下载](https://www.jetbrains.com/idea/features/)
IDE 包就足够了。来自 JetBrains 的 IntelliJ IDEA 用于与本章相关的所有编码。[IntelliJ IDEA 的社区版可从以下网站下载](https://www.jetbrains.com/idea/features/)
# Java 社区
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册