Skip to content

Latest commit

 

History

History
540 lines (389 loc) · 28.3 KB

File metadata and controls

540 lines (389 loc) · 28.3 KB

七、Java 标准和外部库

不使用标准库(也称为 Java 类库JCL)就不可能编写 Java 程序。这就是为什么对这类库的深入了解对于成功编程来说就像对语言本身的了解一样重要。

还有非标准库,称为外部库第三方库,因为它们不包括在 Java 开发工具包JDK)发行版中。它们中的一些早已成为任何程序员工具包的永久固定装置。

要跟踪这些库中可用的所有功能并不容易。这是因为一个集成开发环境IDE)给了您一个关于语言可能性的提示,但是它不能建议尚未导入的包的功能。唯一自动导入的包是java.lang

本章的目的是向读者概述最流行的 JCL 包和外部库的功能

本章讨论的主题如下:

  • Java 类库(JCL)
  • java.lang
  • java.util
  • java.time
  • java.iojava.nio
  • java.sqljavax.sql
  • java.net
  • java.lang.mathjava.math
  • java.awtjavax.swingjavafx
  • 外部库
  • org.junit
  • org.mockito
  • org.apache.log4jorg.slf4j
  • org.apache.commons

Java 类库

JCL 是实现该语言的包的集合。更简单地说,它是 JDK 中包含并准备好使用的.class文件的集合。一旦安装了 Java,就可以将它们作为安装的一部分,并可以开始使用 JCL 类作为构建块来构建应用代码,这些构建块负责许多底层管道。JCL 的丰富性和易用性极大地促进了 Java 的普及。

为了使用 JCL 包,可以导入它,而无需向pom.xml文件添加新的依赖项。这就是标准库和外部库的区别;如果您需要在 Mavenpom.xml配置文件中添加一个库(通常是一个.jar文件)作为依赖项,那么这个库就是一个外部库。否则,它就是一个标准库或 JCL

一些 JCL 包名以java开头。传统上,它们被称为核心 Java 包,而那些以javax开头的包则被称为“扩展”。之所以这样做,可能是因为这些扩展被认为是可选的,甚至可能独立于 JDK 发布。也有人试图推动前扩展库成为一个核心包。但这将需要将包名从java更改为javax,这将打破使用javax包的现有应用。因此,这个想法被抛弃了,所以核心和扩展之间的区别逐渐消失。

这就是为什么,如果你在 Oracle 官方网站上查看 Java API,你会发现不仅有javajavax包被列为标准,还有jdkcom.sunorg.xml以及其他一些包。这些额外的包主要由工具或其他专用应用使用。在我们的书中,我们将主要集中在主流 Java 编程上,只讨论javajavax包。

java.lang

这个包非常重要,使用它不需要导入。JVM 作者决定自动导入它。它包含最常用的 JCL 类:

  • Object类:其他 Java 类的基类
  • Class类:在运行时携带每个加载类的元数据
  • StringStringBufferStringBuilder类:支持类型为String的操作
  • 所有原始类型的包装类:ByteBooleanShortCharacterIntegerLongFloatDouble
  • Number类:前面列出的除Boolean之外的所有数值原始类型的包装类的基类
  • System类:提供对重要系统操作和标准输入输出的访问(在本书的每个代码示例中,我们都使用了System.out对象)
  • Runtime类:提供对执行环境的访问
  • ThreadRunnable接口:创建 Java 线程的基础
  • Iterable接口:由迭代语句使用
  • Math类:提供基本数值运算的方法
  • Throwable类:所有异常的基类
  • Error类:一个异常类,它的所有子类都用来传递应用不应该捕捉到的系统错误
  • Exception类:该类及其直接子类表示选中的异常
  • RuntimeException类:这个类及其子类表示非受检异常,也称为运行时异常
  • ClassLoader类:读取.class文件并将其放入(装入)内存;也可以用来构建定制的类装入器
  • ProcessProcessBuilder类:允许创建其他 JVM 进程
  • 许多其他有用的类和接口

java.util

java.util包的大部分内容专门用于支持 Java 集合:

  • Collection接口:集合的许多其他接口的基础接口,它声明了管理集合元素所需的所有基本方法:size()add()remove()contains()stream()等;它还扩展了java.lang.Iterable接口,继承了iterator()forEach()等方法,这意味着Collection接口的任何实现或其任何子接口ListSetQueueDeque等也可以用于迭代语句中:ArrayListLinkedListHashSetAbstractQueueArrayDeque
  • Map接口和实现它的类:HashMapTreeMap
  • Collections类:提供许多静态方法来分析、操作和转换集合
  • 许多其他集合接口、类和相关工具

我们在第 6 章、“数据结构、泛型和流行工具”中讨论了 Java 集合,并看到了它们的用法示例。

java.util包还包括几个其他有用的类:

  • Objects:提供了各种与对象相关的实用方法,其中一些我们已经在第 6 章、“数据结构、泛型和流行工具”中进行了概述
  • Arrays:包含 160 种静态数组操作方法,其中一些方法我们在第 6 章、“数据结构、泛型和流行工具”中进行了概述
  • Formatter:允许格式化任何原始类型StringDate和其他类型;我们在第 6 章、“数据结构、泛型和流行工具”中演示了它的用法示例
  • OptionalOptionalIntOptionalLongOptionalDouble:这些类通过包装实际值来避免NullPointerException,实际值可以是null,也可以不是null
  • Properties:帮助读取和创建用于应用配置和类似目的的键值对
  • Random:通过生成伪随机数流来补充java.lang.Math.random()方法
  • StringTokeneizer:将String对象分解为由指定分隔符分隔的标记
  • StringJoiner:构造一个字符序列,由指定的分隔符分隔,并可选地由指定的前缀和后缀包围
  • 许多其他有用的工具类,包括支持国际化和 Base64 编码和解码的类

java.time

java.time包包含用于管理日期、时间、时段和持续时间的类。包装包括以下内容:

  • Month枚举
  • DayOfWeek枚举
  • Clock使用时区返回当前时刻、日期和时间的类
  • DurationPeriod类表示并比较不同时间单位中的时间量
  • LocalDateLocalTimeLocalDateTime类表示没有时区的日期和时间
  • ZonedDateTime类表示带时区的日期时间
  • ZoneId类标识时区,如America/Chicago
  • java.time.format.DateTimeFormatter类允许按照国际标准组织ISO)格式,如YYYY-MM-DD等格式显示日期和时间
  • 其他一些支持日期和时间操作的类

我们在第 6 章、“数据结构、泛型和流行工具”中讨论了大多数此类。

java.io以及java.nio

java.iojava.nio包包含支持使用流、序列化和文件系统读写数据的类和接口。这两种包装的区别如下:

  • java.io包类允许在没有缓存的情况下读取/写入数据(我们在第 5 章、“字符串、输入/输出和文件”中讨论过),而java.nio包的类创建了一个缓冲区,允许在填充的缓冲区中来回移动
  • java.io包类阻塞流直到所有数据被读写,而java.nio包的类以非阻塞方式实现(我们将在第 15 章、“反应式编程”中讨论非阻塞方式)

java.sql以及javax.sql

这两个包组成了一个 Java 数据库连接JDBC)API,它允许访问和处理存储在数据源(通常是关系数据库)中的数据。javax.sql包通过提供以下支持来补充java.sql包:

  • DataSource接口作为DriverManager类的替代
  • 连接和语句池
  • 分布式事务
  • 行集

我们将讨论这些包,并在第 10 章“管理数据库中的数据”中看到代码示例。

java.net

java.net包包含支持以下两个级别的应用联网的类:

  • 底层网络,基于:
    • IP 地址
    • 套接字是基本的双向数据通信机制
    • 各种网络接口
  • 高层网络,基于:
    • 通用资源标识符URI
    • 通用资源定位器URL
    • URL 指向的资源的连接

我们将讨论这个包,并在第 11 章、“网络编程”中看到代码示例。

java.lang.math以及java.math

java.lang.math包包含执行基本数值运算的方法,例如计算两个数值的最小值和最大值、绝对值、初等指数、对数、平方根、三角函数以及许多其他数学运算。

java.math包通过允许使用BigDecimalBigInteger类处理更大的数字,补充了java.lang包的 Java 基本类型和包装类。

Java.awtjavax.swing,和 JavaFX

第一个支持为桌面应用构建图形用户界面GUI)的 Java 库是java.awt包中的抽象窗口工具包AWT)。它为执行平台的本机系统提供了一个接口,允许创建和管理窗口、布局和事件。它还具有基本的 GUI 小部件(如文本字段、按钮和菜单),提供对系统托盘的访问,并允许启动 Web 浏览器和通过 Java 代码向客户端发送电子邮件。它对本机代码的高度依赖使得基于 AWT 的 GUI 在不同的平台上看起来不同。

1997 年,Sun 微系统公司和 Netscape 通信公司推出了 Java 基础类,后来被称为 Swing,并将它们放在javax.swing包中。使用 Swing 构建的 GUI 组件能够模拟一些本机平台的外观,但也允许您插入不依赖于它运行的平台的外观。它通过添加选项卡面板、滚动窗格、表格和列表扩展了 GUI 可以拥有的小部件列表。Swing 组件被称为轻量级组件,因为它们不依赖于本机代码,并且完全用 Java 实现。

2007 年,Sun 微系统公司宣布创建 JavaFX,JavaFX 最终成为一个软件平台,用于在许多不同的设备上创建和交付桌面应用。它旨在取代 Swing 作为 JavaSE 的标准 GUI 库。JavaFX 框架位于以javafx开头的包中,支持所有主要的桌面操作系统(DOS)和多个移动操作系统,包括 Symbian 操作系统、Windows 移动操作系统和一些专有的实时操作系统。

JavaFX 基于层叠样式表CSS),将平滑动画、Web 视图、音频和视频播放以及样式的支持添加到 GUI 开发人员的库中。但是,Swing 有更多的组件和第三方库,因此使用 JavaFX 可能需要创建很久以前在 Swing 中实现的自定义组件和管道。这就是为什么,尽管 JavaFX 被推荐为桌面 GUI 实现的首选,但根据 Oracle 网站上的官方回应,Swing 在可预见的未来仍将是 Java 的一部分。所以,可以继续使用 Swing,但如果可能,最好切换到 JavaFX。

我们将讨论 JavaFX,并在第 12 章、“Java GUI 编程”中看到代码示例。

外部库

最常用的第三方非 JCL 库的不同列表包括 20 到 100 个库。在本节中,我们将讨论这些列表中的大多数。所有这些都是开源项目。

org.junit

org.junit包是开源测试框架 JUnit 的根包。它可以作为以下pom.xml依赖项添加到项目中:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

前面的dependency标记中的scope值告诉 Maven 只有在测试代码要运行时才包含库.jar文件,而不是包含在应用的生产.jar文件中。有了依赖关系,现在就可以创建测试了。您可以自己编写代码,也可以让 IDE 使用以下步骤为您编写代码:

  1. 右键单击要测试的类名

  2. 选择“转到”

  3. 选择“测试”

  4. 单击“创建新测试”

  5. 单击要测试的类的方法的复选框

  6. 使用@Test注解为生成的测试方法编写代码

  7. 如有必要,添加带有@Before@After注解的方法

假设我们有以下类:

public class SomeClass {
    public int multiplyByTwo(int i){
        return i * 2;
    }
}

如果您遵循前面列出的步骤,那么在test源代码树下将创建以下测试类:

import org.junit.Test;
public class SomeClassTest {
    @Test
    public void multiplyByTwo() {
    }
}

现在您可以实现如下的void multiplyByTwo()方法:

@Test
public void multiplyByTwo() {
    SomeClass someClass = new SomeClass();
    int result = someClass.multiplyByTwo(2);
    Assert.assertEquals(4, result);
}

一个单元是一段可以测试的最小代码,因此它的名字。最佳测试实践将方法视为最小的可测试单元。这就是为什么单元测试通常测试方法。

org.mockito

单元测试经常面临的问题之一是需要测试使用第三方库、数据源或其他类的方法的方法。在测试时,您希望控制所有的输入,以便可以预测测试代码的预期结果。在这一点上,模拟或模拟被测试代码与之交互的对象的行为的技术就派上了用场。

一个开源框架 Mockito(org.mockito根包名)允许完成模拟对象的创建。使用它非常简单和直接。这里有一个简单的例子。假设我们需要测试另一个SomeClass方法:

public class SomeClass {
    public int multiplyByTwoTheValueFromSomeOtherClass(SomeOtherClass 
                                                        someOtherClass){
        return someOtherClass.getValue() * 2;
    }
}

为了测试这个方法,我们需要确保getValue()方法返回一个特定的值,所以我们要模拟这个方法。为此,请执行以下步骤:

  1. 向 Mavenpom.xml配置文件添加依赖项:
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.23.4</version>
            <scope>test</scope>
        </dependency>
  1. 为需要模拟的类调用Mockito.mock()方法:
SomeOtherClass mo = Mockito.mock(SomeOtherClass.class);
  1. 设置需要从方法返回的值:
Mockito.when(mo.getValue()).thenReturn(5);
  1. 现在,您可以将模拟对象作为参数传递到正在测试的调用模拟方法的方法中:
SomeClass someClass = new SomeClass();
int result = someClass.multiplyByTwoTheValueFromSomeOtherClass(mo);
  1. 模拟方法返回预定义的结果:
Assert.assertEquals(10, result);
  1. 完成上述步骤后,测试方法如下所示:
@Test
public void multiplyByTwoTheValueFromSomeOtherClass() {
    SomeOtherClass mo = Mockito.mock(SomeOtherClass.class);
    Mockito.when(mo.getValue()).thenReturn(5);

    SomeClass someClass = new SomeClass();
    int result = 
           someClass.multiplyByTwoTheValueFromSomeOtherClass(mo);
    Assert.assertEquals(10, result);
}

Mockito 有一定的局限性。例如,不能模拟静态方法和私有方法。否则,通过可靠地预测所使用的第三方类的结果来隔离正在测试的代码是一个很好的方法

org.apache.log4j以及org.slf4j

在这本书中,我们使用System.out来显示结果。在实际应用中,也可以这样做,并将输出重定向到一个文件,例如,用于以后的分析。在做了一段时间之后,您会注意到您需要关于每个输出的更多细节:例如,每个语句的日期和时间以及生成日志语句的类名。随着代码库的增长,您会发现最好将不同子系统或包的输出发送到不同的文件,或者在一切正常时关闭一些消息,在检测到问题并且需要有关代码行为的更详细信息时再打开这些消息。您不希望日志文件的大小无法控制地增长。

您可以编写自己的代码来完成这一切。但是有几种框架是基于配置文件中的设置来实现的,您可以在每次需要更改日志记录行为时更改这些设置。最常用的两个框架是log4j(发音为 LOG-FOUR-JAY)和slf4j(发音为 S-L-F-FOUR-JAY)。

事实上,这两个框架并不是对手。slf4j框架是一个外观,提供对底层实际日志框架的统一访问,其中一个也可以是log4j。当程序员事先不知道使用库的应用将使用什么样的日志框架时,这种外观在库开发期间尤其有用。通过使用slf4j编写代码,程序员允许稍后将其配置为使用任何日志系统。

因此,如果您的代码将仅由您的团队开发的应用使用,那么仅使用log4j就足够了。否则,请考虑使用slf4j

并且,与任何第三方库一样,在使用log4j框架之前,必须向 Mavenpom.xml配置文件添加相应的依赖关系:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.11.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.11.1</version>
</dependency>

例如,以下是如何使用框架:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SomeClass {
    static final Logger logger = 
                        LogManager.getLogger(SomeClass.class.getName());
    public int multiplyByTwoTheValueFromSomeOtherClass(SomeOtherClass 
                                                        someOtherClass){
        if(someOtherClass == null){
            logger.error("The parameter should not be null");
            System.exit(1);
        }
        return someOtherClass.getValue() * 2;
    }
    public static void main(String... args){
        new SomeClass().multiplyByTwoTheValueFromSomeOtherClass(null);
    }
}

如果我们运行前面的main()方法,结果如下:

18:34:07.672 [main] ERROR SomeClass - The parameter should not be null
Process finished with exit code 1

如您所见,如果项目中没有添加特定于log4j的配置文件,log4j将在DefaultConfiguration类中提供默认配置。默认配置如下:

  1. 日志消息将转到控制台
  2. 消息的模式将是"%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
  3. logging的级别为Level.ERROR(其他级别为OFFFATALWARNINFODEBUGTRACEALL

通过使用以下内容将log4j2.xml文件添加到resources文件夹(Maven 将其放置在类路径上),可以获得相同的结果:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level 
                                                %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

如果这对您来说还不够好,可以将配置更改为记录不同级别的消息、不同的文件等等。阅读log4J文档

org.apache.commons

org.apache.commons包是另一个流行的库,它是作为一个名为 Apache Commons 的项目开发的。它由一个名为 Apache 软件基金会的开源程序员社区维护。这个组织是 1999 年由阿帕奇集团成立的。自 1993 年以来,Apache 小组一直围绕 Apache HTTP 服务器的开发而发展。Apache HTTP 服务器是一个开源的跨平台 Web 服务器,自 1996 年 4 月以来一直是最流行的 Web 服务器。

Apache Commons 项目包括以下三个部分:

  • Commons Sandbox:Java 组件开发的工作区;您可以为那里的开放源码工作做出贡献
  • Commons Dormant:当前处于非活动状态的组件的存储库;您可以在那里使用代码,但必须自己构建组件,因为这些组件可能不会在不久的将来发布
  • Commons Proper:可重用的 Java 组件,组成实际的org.apache.commons

我们讨论了第 5 章中的org.apache.commons.io包、“字符串、输入/输出和文件”。 在下面的小节中,我们将只讨论三个最受欢迎的通用包:

  • org.apache.commons.lang3
  • org.apache.commons.collections4
  • org.apache.commons.codec.binary

但是org.apache.commons下还有更多的包,其中包含数千个类,这些类很容易使用,可以帮助您的代码更加优雅和高效。

langlang3

org.apache.commons.lang3包实际上是org.apache.commons.lang包的版本 3。创建新包的决定是由于版本 3 中引入的更改是向后不兼容的,这意味着使用先前版本的org.apache.commons.lang包的现有应用在升级到版本 3 后可能会停止工作。但在大多数主流编程中,向import语句添加3(作为迁移到新版本的方法)通常不会破坏任何东西。

据文献记载,org.apache.commons.lang3包提供了高度可重用的静态实用方法,主要是为java.lang类增加价值。这里有几个值得注意的例子:

  • ArrayUtils类:允许搜索和操作数组;我们在第 6 章、“数据结构、泛型和流行工具”中讨论和演示了它
  • ClassUtils类:提供类的元数据
  • ObjectUtils类:检查null的对象数组,比较对象,以null安全的方式计算对象数组的中值和最小/最大值;我们在第 6 章、“数据结构、泛型和流行工具”中讨论并演示了它
  • SystemUtils类:提供执行环境的相关信息
  • ThreadUtils类:查找当前正在运行的线程的信息
  • Validate类:验证单个值和集合,比较它们,检查null,匹配,并执行许多其他验证
  • RandomStringUtils类:根据不同字符集的字符生成String对象
  • StringUtils类:我们在第 5 章中讨论了“字符串、输入/输出和文件”

collections4

尽管从表面上看,org.apache.commons.collections4包的内容与org.apache.commons.collections包(即包的版本 3)的内容非常相似,但迁移到版本 4 可能不如在import语句中添加“4”那么顺利。版本 4 删除了不推荐使用的类,添加了泛型和其他与以前版本不兼容的特性。

要想得到一个在这个包或它的一个子包中不存在的集合类型或集合工具,必须很困难。以下只是包含的功能和工具的高级列表:

  • Bag集合接口,具有每个对象的多个副本
  • 实现Bag接口的十几个类;例如,下面是如何使用HashBag类:
        Bag<String> bag = new HashBag<>();
        bag.add("one", 4);
        System.out.println(bag);                 //prints: [4:one]
        bag.remove("one", 1);
        System.out.println(bag);                 //prints: [3:one]
        System.out.println(bag.getCount("one")); //prints: 3
  • 转换基于Bag的集合的BagUtils
  • BidiMap双向映射的接口,不仅可以按键检索值,还可以按值检索键;它有几个实现,例如:
        BidiMap<Integer, String> bidi = new TreeBidiMap<>();
        bidi.put(2, "two");
        bidi.put(3, "three");
        System.out.println(bidi);             //prints: {2=two, 3=three}
        System.out.println(bidi.inverseBidiMap()); 
                                              //prints: {three=3, two=2}
        System.out.println(bidi.get(3));      //prints: three
        System.out.println(bidi.getKey("three")); //prints: 3
        bidi.removeValue("three"); 
        System.out.println(bidi);              //prints: {2=two}
  • MapIterator提供简单快速的映射迭代接口,例如:
        IterableMap<Integer, String> map =
                           new HashedMap<>(Map.of(1, "one", 2, "two"));
        MapIterator it = map.mapIterator();
        while (it.hasNext()) {
            Object key = it.next();
            Object value = it.getValue();
            System.out.print(key + ", " + value + ", "); 
                                              //prints: 2, two, 1, one, 
            if(((Integer)key) == 2){
                it.setValue("three");
            }
        }
        System.out.println("\n" + map);      //prints: {2=three, 1=one}
  • 使元素保持一定顺序的有序映射和集合,如List,例如:
        OrderedMap<Integer, String> map = new LinkedMap<>();
        map.put(4, "four");
        map.put(7, "seven");
        map.put(12, "twelve");
        System.out.println(map.firstKey()); //prints: 4
        System.out.println(map.nextKey(2)); //prints: null
        System.out.println(map.nextKey(7)); //prints: 12
        System.out.println(map.nextKey(4)); //prints: 7
  • 引用映射;它们的键和/或值可以由垃圾收集器删除
  • Comparator接口的各种实现
  • Iterator接口的各种实现
  • 将数组和枚举转换为集合的类
  • 允许测试或创建集合的并集、交集和闭包的工具
  • CollectionUtilsListUtilsMapUtilsMultiMapUtilsMultiSetUtilsQueueUtilsSetUtils以及许多其他特定于接口的工具类

阅读包装文件了解更多细节。

codec.binary

org.apache.commons.codec.binary包提供对 Base64、Base32、二进制和十六进制字符串编码和解码的支持。编码是必要的,以确保您跨不同系统发送的数据不会因为不同协议中字符范围的限制而在途中更改。此外,有些系统将发送的数据解释为控制字符(例如调制解调器)。

下面的代码片段演示了这个包的Base64类的基本编码和解码功能:

String encodedStr = 
           new String(Base64.encodeBase64("Hello, World!".getBytes()));
System.out.println(encodedStr);         //prints: SGVsbG8sIFdvcmxkIQ==

System.out.println(Base64.isBase64(encodedStr));        //prints: true

String decodedStr = 
               new String(Base64.decodeBase64(encodedStr.getBytes()));
System.out.println(decodedStr);                 //prints: Hello, World!

您可以在 ApacheCommons 项目站点上阅读关于这个包的更多信息。

总结

在本章中,我们概述了 JCL 最流行的包的功能:java.langjava.utiljava.timejava.iojava.niojava.sqljavax.sqljava.netjava.lang.mathjava.mathjava.awtjavax.swingjavafx

最流行的外部库是由org.junitorg.mockitoorg.apache.log4jorg.slf4jorg.apache.commons包表示的,当这些功能已经存在并且可以直接导入和使用时,它可以帮助读者避免编写自定义代码。

在下一章中,我们将讨论 Java 线程并演示它们的用法。我们还将解释并行处理和并发处理之间的区别。我们将演示如何创建线程以及如何执行、监视和停止它。它不仅对准备为多线程处理编写代码的读者非常有用,而且对那些希望提高对 JVM 工作原理的理解的读者也非常有用,这将是下一章的主题。

测验

  1. 什么是 Java 类库?选择所有适用的选项:

    1. 编译后的类的集合
    2. Java 安装附带的包
    3. Maven 自动添加到类路径的.jar文件
    4. 任何用 Java 编写的库
  2. 什么是 Java 外部库?选择所有适用的选项:

  3. java.lang包中包含哪些功能?选择所有适用的选项:

  4. java.util包中包含哪些功能?选择所有适用的选项:

  5. java.time包中包含哪些功能?选择所有适用的选项:

  6. java.io包中包含哪些功能?选择所有适用的选项:

  7. java.sql包中包含哪些功能?选择所有适用的选项:

  8. java.net包中包含哪些功能?选择所有适用的选项:

  9. java.math包中包含哪些功能?选择所有适用的选项:

  10. javafx包中包含哪些功能?选择所有适用的选项:

  11. org.junit包中包含哪些功能?选择所有适用的选项:

  12. org.mockito包中包含哪些功能?选择所有适用的选项:

  13. org.apache.log4j包中包含哪些功能?选择所有适用的选项:

  14. org.apache.commons.lang3包中包含哪些功能?选择所有适用的选项:

  15. org.apache.commons.collections4包中包含哪些功能?选择所有适用的选项:

  16. org.apache.commons.codec.binary包中包含哪些功能?选择所有适用的选项:*