甚至我们在本书中编写的第一个程序也使用了 JDK 中包含的一个库,称为标准库。如果不使用标准库,就不可能编写一个非常重要的程序。这就是为什么对这些库的熟悉与对语言本身的了解一样对成功编程至关重要的原因。
还有一些非标准库,它们被称为外部库或第三方库,因为它们不包括在 JDK 发行版中,但它们的使用频率几乎相同。他们早已成为任何程序员工具包的永久成员。同时,跟踪这些库中可用的所有功能并不像跟上 Java 本身那么容易。这是因为 IDE 为您提供了关于语言可能性的提示,但它不能建议尚未导入的包的功能。唯一一个自动导入且不需要导入的包是java.lang
,这将是我们在本章中的第一个概述。
本章讨论的主题包括:
- 什么是标准库和外部库?
- Java 标准库概述
- 包装
java.lang
- 包装
java.util
- 包装
java.io
和java.nio
- 包装
java.sql
和javax.sql
- 包装
java.net
- 包装
java.math
- 包装
java.awt
、javax.swing
和javafx
- Java 外部库概述
- 图书馆
org.junit
- 图书馆
org.mockito
- 图书馆
org.log4j
和org.slf4j
- 图书馆
org.apache.commons
- 练习-使用
java.time.LocalDateTime
标准库(也称为类标准库)是可用于该语言所有实现的类和接口的集合。更简单地说,这意味着,它是 JDK 中包含的准备使用的.class
文件的集合。一旦您安装了 Java,您就可以将它们作为安装的一部分,并可以开始使用标准库的类作为构建块来构建应用程序代码,这些构建块负责许多底层管道。标准库的丰富性和易用性极大地促进了 Java 的普及。
这些集合是按包组织的。这就是为什么程序员称之为 Java 标准库(Java standard library)而不是称之为 Java 标准库(Java standard library),因为为了使用它们,您必须根据需要导入库包,因此它们被视为许多库。
它们也是标准的,因为 Maven 会自动将它们添加到类路径中,所以我们不需要将它们作为依赖项列在pom.xml
文件中。这就是标准库和外部库的区别;如果您需要在 Maven 配置文件pom.xml
中添加一个库(通常为.jar
文件)作为依赖项,则该库是一个外部库,也称为第三方库。否则,它是一个标准库。
在以下各节中,我们将对每个类别进行概述,并进一步了解一些最流行的标准库和外部库。
如果您在 internet 上搜索“JavaAPI”,您将发现 JDK 中包含的所有包的在线描述。一些包名称以java
开头。它们传统上被称为核心 Java 包,而那些以javax
开头的被称为扩展。这样做可能是因为扩展被认为是可选的,甚至可能独立于 JDK 发布。也有人试图将以前的扩展库提升为核心包,但这需要将包的名称从 Java 更改为 Javax,这将破坏现有的应用程序。因此,这个想法被抛弃了,扩展成为 JDK 的标准部分,成为核心,核心和扩展之间的区别逐渐消失。
这就是为什么如果您查看 Oracle 网站上的官方 Java API,您将看到不仅有java
和javax
包被列为标准,还有jdk
、com.sun
、org.xml
和其他一些包也被列为标准。这些额外的包主要由工具或其他专用应用程序使用。在本书中,我们将主要关注主流 Java 编程,只讨论java
和javax
包。
这个包对于所有 Java 类库来说都是非常基本的,因此它不仅不需要作为依赖项列在 Maven 配置pom.xml
文件中(Java 标准库的所有其他包也不需要作为依赖项列出来),而且它的成员甚至不需要为了使用它们而导入。任何包的任何成员,无论是否为标准,都必须导入或使用其完全限定名,但java.lang
包的类和接口除外。原因是它包含两个最重要和最常用的 Java 类:
此外,java.lang
包还包括:
- 支持类型为
String
的操作的类String
、StringBuffer
和StringBuilders
(更多详细信息和用法示例,请参见第 15 章、管理对象、字符串、时间和随机数) - 所有原语类型的包装类:
Byte
、Boolean
、Short
、Character
、Integer
、Long
、Float
和Double
(有关包装类及其用法的详细信息,请参见第 9 章、运算符、表达式和语句) Number
类,前面列出的数字包装类的基类System
类,提供对重要系统操作和标准输入输出的访问(我们在本书的每个代码示例中都使用了System.out
对象)Runtime
类,提供对执行环境的访问Thread
类和Runnable
接口是创建 Java 线程的基础- 迭代语句使用的
Iterable
接口(参见第 9 章、运算符、表达式、语句 **Math
类,提供基本数值操作的方法*Throwable
类–所有异常的基类* 异常类Error
及其所有子类,用于传递应用程序不应捕获的系统错误*Exception
类及其多个子类,表示已检查的异常(参见第 10 章、控制流语句)*RuntimeException
类及其多个子类表示未检查的异常,也称为运行时异常(参见第 10 章、控制流语句)*ClassLoader
类,它允许加载类,并可用于构建定制的类加载器*Process
和ProcessBuilder
类,它们允许创建外部进程* 许多其他有用的类和接口*
*# java.util
这是另一个非常常用的包。其大部分内容专用于支持收藏:
Collection
接口–许多采集接口的基础接口。它包含管理集合元素所需的所有基本方法:size()
、add()
、remove()
、contains()
、iterator()
、stream()
等。请注意,Collection
接口扩展了Iterable
接口并从中继承了iterator()
方法。这意味着Collection
接口的任何实现都可以在迭代语句中使用。- 扩展
Collection
接口的接口:List
、Set
、Queue
、Deque
等。 - 许多实现上述接口的类:
ArrayList
、LinkedList
、HashSet
、AbstractQueue
、ArrayDeque
等。 Map
接口和实现它的类:HashMap
、TreeMap
等。Collections
类,它提供了许多用于操作和转换集合的静态方法。- 许多其他集合接口、类和相关实用程序。
我们将更多地讨论集合,并在第 13 章、Java 集合中看到它们的用法示例。
java.util
包还包括其他几个有用的类:
Objects
类提供了各种与对象相关的实用方法,包括两个对象的空安全equals()
Arrays
类包含 200 多个静态方法来操作数组Formatter
类允许格式化任何基元类型,如String
、Date
和其他类型- 类
Optional
、OptionalInt
、OptionalLong
和OptionalDouble
,它们通过包装实际值来帮助避免NullPointerException
,不管实际值是否为空 Properties
类帮助读取和创建用于配置和类似目的的键值对Random
类通过生成伪随机数流来补充Math.random()
方法Stack
类允许创建对象的后进先出(后进先出堆栈StringTokeneizer
类将String
对象分解为由指定分隔符分隔的标记StringJoiner
类构造由指定分隔符分隔的字符序列,并可选地由指定的前缀和后缀包围- 许多其他有用的实用程序类,包括国际化支持类和 base64 编码和解码
这是管理日期、时间、实例和持续时间的主要 JavaAPI。一揽子计划包括:
- 枚举
Month
- 枚举
DayOfWeek
Clock
类,它使用时区立即返回当前日期和时间Duration
和Period
类表示并比较不同时间单位中的时间量LocalDate
、LocalTime
、LocalDateTime
类表示没有时区的日期和时间ZonedDateTime
类表示带时区的日期时间ZoneId
类标识一个时区,如美国/芝加哥- 其他一些支持日期和时间操作的类
java.time.format.DateTimeFormatter
类允许您按照国际标准组织(ISO)格式显示日期和时间,并基于 YYYY-MM-DD 等模式。
我们将进一步讨论日期和时间处理,参见第 15 章、管理对象、字符串、时间和随机数中的代码示例。
java.io
和java.nio
包包含支持使用流、序列化和文件系统读写数据的类。这两个包的区别如下:
java.io
允许我们在不缓存的情况下读取/写入数据java.nio
创建一个缓冲区,允许程序在缓冲区中来回移动java.io
的类方法阻塞流,直到读取或写入所有数据java.nio
表示数据读写的非阻塞方式
这两个包组成了Java 数据库连接(JDBC)API,它允许访问和处理存储在数据源(通常是关系数据库)中的数据。包javax.sql
补充了java.sql
包,为以下方面提供支持:
DataSource
接口作为DriverManager
的替代- 连接池和语句池
- 分布式事务
- 行集
我们将进一步讨论如何使用这些包,并在第 16 章、数据库编程中查看代码示例。
java.net
包包含支持两个级别的应用程序联网的类:
-
低层网络,基于:
- IP 地址
- 套接字,是基本的双向数据通信机制
- 各种网络接口
-
高级网络,基于:
- 通用资源标识符(URI)
- 通用资源定位器(URL)
- 到 URL 指向的资源的连接
该包通过允许使用类BigDecimal
和BigInteger
处理更大的数字,补充了java.lang
包的 Java 基本类型和包装类。
第一个支持为桌面应用程序构建图形用户界面(GUI)的 Java 库是java.awt
包中的抽象窗口工具包(AWT)。它为执行平台的本机系统提供了一个接口,允许创建和管理窗口、布局和事件。它还提供了从浏览器到浏览器的基本菜单和窗口小部件。它对本机代码的高度依赖使得基于 AWT 的 GUI 在不同平台上看起来有所不同。
1997,Sun MetaSnices 和 Netscape 通信公司引入 java 基础类,后来称为 Swing,并放入包 Tyt0.使用 Swing 构建的 GUI 组件可以模拟一些本机平台的外观,但也允许用户插入不依赖于其运行平台的外观。它通过添加选项卡式面板、滚动窗格、表格和列表扩展了 GUI 可能拥有的小部件列表。Swing 组件被称为轻量级组件,因为它们不依赖于本机代码,并且完全用 Java 实现。
2007 年,Sun Microsystems 发布了 JavaFX,它最终成为一个软件平台,用于在许多不同的设备上创建和交付桌面应用程序,以取代 Swing 作为 JavaSE 的标准 GUI 库。它位于以javafx
开头的包中,支持所有主要的桌面操作系统和多个移动操作系统,包括 Symbian 操作系统、Windows mobile 和一些专有的实时操作系统。
JavaFX 为 GUI 开发人员增加了对平滑动画、web 视图、音频和视频播放以及基于级联样式表(CSS的样式的支持。然而,Swing 有更多的组件和第三方库,因此使用 JavaFX 可能需要创建在 Swing 中很久以前就已经实现的自定义组件和管道。这就是为什么根据 Oracle 网站(上的官方回复,尽管 JavaFX 被推荐为桌面 GUI 实现的首选,但 Swing 在可预见的未来仍将是 Java 的一部分 http://www.oracle.com/technetwork/java/javafx/overview/faq-1446554.html#6 )。因此,可以继续使用 Swing,但如果可能,最好切换到 JavaFX。
各种统计数据包括 20 个或 100 个最常用的第三方库列表中的不同名称。在本节中,我们将讨论这些列表中的大部分。所有这些都是开源项目。
JUnit 是一个开源测试框架,其根包名为org.junit
。在本书的几个代码示例中都使用了它。如您所见,它的设置和使用非常简单(我们已经在第 4 章、您的第一个 Java 项目中描述了步骤):
- 向 Maven 配置文件
pom.xml
添加依赖项 - 手动创建测试,或右键单击要测试的类名,选择“转到”,然后选择“测试”,然后选择“创建新测试”,然后检查要测试的类的方法
- 使用注释
@Test
为生成的测试方法编写代码 - 如有必要,添加带有注释
@Before
和@After
的方法
“单元”是可以测试的最小代码段,因此是名称。最好的测试实践认为方法是最小的可测试单元。这就是为什么单元测试通常是测试方法。
单元测试经常面临的问题之一是需要测试使用第三方库、数据源或其他类的方法的方法。在测试时,您希望控制所有输入,以便能够准确预测测试代码的预期结果。这就是模拟或模拟被测试代码与之交互的对象行为的技术的用武之地。
开源框架 Mockito(根包名称org.mockito
)允许您准确地完成这一点——创建模拟对象。它使用起来非常简单和直接。这里有一个简单的例子:
- 向 Maven 配置文件
pom.xml
添加依赖项 - 为需要模拟的类调用
mock()
方法:SomelClass mo = Mockito.mock(SomeClass.class)
- 设置需要从方法返回的值:
Mockito.when(mo.doSomething(10)).thenReturn(20)
- 现在,将模拟对象作为参数传递给正在测试的调用模拟方法的方法
- mock 方法返回预定义的结果
Mockito 有一定的局限性。例如,不能模拟静态方法和私有方法。否则,通过可靠地预测所用方法的结果来隔离您正在测试的代码是一种很好的方法。该框架的名称和徽标基于mojitos——一种饮料。
在本书中,我们使用了System.out
对象来显示中间和最终结果的输出。在实际应用程序中,您也可以这样做,并将输出重定向到文件,例如,用于以后的分析。在做了一段时间后,您会注意到需要关于每个输出的更多详细信息—例如,每个语句的日期和时间,或者生成该语句的类名。随着代码库的增长,您会发现最好将不同子系统或包的输出发送到不同的文件,或者在一切正常时关闭一些消息,在检测到问题并且需要有关代码行为的更详细信息时重新打开这些消息。
您可以编写自己的程序来完成所有这些,但是有几个框架可以根据配置文件中的设置来完成,您可以在每次需要更改消息行为时更改这些设置。应用程序日志中使用的【JAY-log】和【T4-T0】等四条消息,最常用的是【应用程序日志】中的【JAY-log】和【T4-T0】这四条消息。
事实上,这两个框架并不是竞争对手。slf4j
是一个门面,提供对底层日志框架的统一访问,其中一个也可以是log4j
。当程序员事先不知道使用库的应用程序将使用什么样的日志框架时,这种外观在库开发期间尤其有用。通过使用slf4j
编写代码,程序员允许用户稍后将其配置为使用任何日志系统。
因此,如果您的代码将仅由您的团队开发的应用程序使用,并且将在生产中支持,那么只使用log4j
就足够了。否则,考虑使用 OutT1。
而且,与任何第三方库一样,在使用任何日志框架之前,必须向 Maven 配置文件pom.xml
添加相应的依赖项。
在上一节中,我们讨论了一个具有org.apache
根名称的包—包org.apache.log4j
。
包 AutoT0.是另一个流行的库,代表一个名为 Apache Care 的项目,它被称为 Apache 软件基金会的开源程序员社区维护。该组织于 1999 年由 Apache 集团成立。自 1993 年以来,Apache 集团一直围绕着 Apache HTTP 服务器的开发而发展。ApacheHTTP 服务器是一种开源的跨平台 web 服务器,自 1996 年 4 月以来一直是最流行的。来自维基百科的一篇文章:
“截至 2016 年 7 月,据估计,它服务于 46%的所有活跃网站和 43%的百万顶级网站。“Apache”这个名字是从对土著美洲阿帕奇民族的尊重中选择的,因为他们在战争战略方面的高超技能和他们无尽的耐力而闻名。这也让人联想到了“一个零碎的 web 服务器”“-由一系列修补程序组成的服务器,但这不是其来源”
Apache Commons 项目包括三个部分:
- Commons 沙盒:用于 Java 组件开发的工作空间;您可以在那里为开源工作做出贡献
- Commons 休眠:当前处于非活动状态的组件的存储库;您可以在那里使用代码,但必须自己构建组件,因为这些组件可能不会在不久的将来发布
- Commons 本体:可重用 Java 组件,组成实际库
org.apache.commons
在以下小节中,我们将只讨论 Commons Prime 最流行的四个包:
org.apache.commons.io
org.apache.commons.lang
org.apache.commons.lang3
org.apache.commons.codec.binary
然而,在org.apache.commons
下还有更多的包,其中包含数千个有用的类,这些类可以很容易地使用,并有助于使您的代码优雅高效。
org.apache.commons.io
包的所有类都包含在根包和五个子包中:
-
根包
org.apache.commons.io
包含具有执行常见任务的静态方法的实用程序类,例如,一个流行的FileUtils
类,它允许对所需文件执行所有可能的操作:- 写入文件
- 从文件中读取
- 创建一个目录,包括父目录
- 复制文件和目录
- 删除文件和目录
- 与 URL 之间的转换
- 按筛选器和扩展名列出文件和目录
- 比较文件内容
- 文件上次更改日期
- 计算校验和
-
org.apache.commons.io.input
包包含支持基于InputStream
和Reader
实现的数据输入的类,如XmlStreamReader
或ReversedLinesFileReader
-
org.apache.commons.io.output
包包含支持基于OutputStream
和Writer
实现的数据输出的类,如XmlStreamWriter
或StringBuilderWriter
-
org.apache.commons.io.filefilter
包包含用作文件过滤器的类,如DirectoryFileFilter
或RegexFileFilter
-
org.apache.commons.io.comparato
包包含各种文件的java.util.Comparator
实现,如NameFileComparator
-
org.apache.commons.io.monitor
包提供用于监控文件系统事件(目录和文件创建、更新和删除事件)的组件,例如FileAlterationMonitor
,它实现Runnable
并生成一个监控线程,以指定的间隔触发任何已注册的FileAlterationObserver
包org.apache.commons.lang3
实际上是包org.apache.commons.lang
的版本 3。创建新包的决定是由于版本 3 中引入的更改是向后不兼容的。这意味着使用先前版本的org.apache.commons.lang
包的现有应用程序在升级到版本 3 后可能会停止工作。但是,在大多数主流编程中,在 import 语句中添加 3(作为迁移到新版本的方式)可能不会破坏任何东西。
根据文档“org.apache.commons.lang3 包提供了高度可重用的静态实用程序方法,主要涉及为 java.lang 类
增加价值。以下是几个值得注意的示例:
ArrayUtils
类允许搜索和操作数组。ClassUtils
类提供了一些关于类的元数据。ObjectUtils
类检查对象数组中的null
,比较对象,并以空安全的方式计算对象数组的中值和最小/最大值。SystemUtils
类提供有关执行环境的信息。ThreadUtils
类查找有关当前正在运行的线程的信息。Validate
类验证单个值和集合:比较它们,检查null
,匹配,并执行许多其他验证。RandomStringUtils
类从各种字符集的字符生成String
对象。StringUtils
类是许多程序员的最爱。以下是它提供的空安全操作列表:isEmpty
/isBlank
:检查String
值是否包含文本trim
/strip
:删除前导和尾随空格equals
/compare
:比较两个空安全字符串startsWith
:检查String
值是否以某个前缀 null safe 开头endsWith
:检查String
值是否以某个后缀 null safe 结尾indexOf
/lastIndexOf
/contains
:提供检查的空安全索引indexOfAny
/lastIndexOfAny
/indexOfAnyBut
/lastIndexOfAnyBut
:提供一组String
值中任意一个的索引containsOnly
/containsNone
/containsAny
:检查String
值是否仅包含/无/任何特定字符substring
/left
/right
/mid
:支持空安全子串提取substringBefore
/substringAfter
/substringBetween
:相对于其他字符串执行子字符串提取split
/join
:通过特定分隔符将String
值拆分为子字符串数组,反之亦然remove
/delete
:删除String
值的一部分replace
/overlay
:搜索一个String
值并用另一个值替换一个String
值chomp
/chop
:删除String
值的最后一部分appendIfMissing
:如果String
值不存在,则在其末尾添加后缀prependIfMissing
:如果String
值不存在,则在其开头加前缀leftPad
/rightPad
/center
/repeat
:此焊盘为String
值upperCase
/lowerCase
/swapCase
/capitalize
/uncapitalize
:这改变了String
值的情况countMatches
:统计一个String
值在另一个String
值中出现的次数isAlpha
/isNumeric
/isWhitespace
/isAsciiPrintable
:检查String
值中的字符defaultString
:这可以防止String
值的null
输入rotate
:以String
值旋转(循环移位)字符reverse
/reverseDelimited
:这将反转String
值中的字符或分隔字符组abbreviate
:使用省略号或其他给定String
值缩写String
值difference
:比较String
值并报告其差异levenshteinDistance
:将一个String
值更改为另一个String
值所需的更改次数
此库的内容不在本入门课程的范围内。所以,我们将只提到这个库提供了对 Base64、Base32、二进制和十六进制字符串编码和解码的支持。
由于不同协议中字符范围的限制,编码是确保跨不同系统发送的数据不会在途中更改的必要条件。此外,一些系统将发送的数据解释为控制字符(例如调制解调器)。
String
类的indexOf()
方法和StringUtils
类的indexOf()
方法有什么区别?
String
类的indexOf()
方法不处理null
。下面是一些演示代码:
String s = null;
int i = StringUtils.indexOf(s, "abc"); //return -1
s.indexOf("abc"); //throws NullPointerException
在本章中,读者了解了 JDK 中包含的 Java 标准库以及一些最流行的外部库或第三方库的内容。特别是,我们仔细研究了标准包java.lang
和java.util
;比较包装java.io
和java.nio
、java.sql
和javax.sql
、java.awt
、javax.swing
和javafx
;并对包装java.net
和java.math
进行了审查。
我们还对流行的外部库org.junit
、org.mockito
、org.apache.log4j
、org.slf4j
以及 Apache Commons 项目的几个包org.apache.commons.io
、org.apache.commons.lang
、org.apache.commons.lang3
和org.apache.commons.codec.binary
进行了概述。
下一章将帮助读者更详细地熟悉最广泛使用的 Java 类。代码示例将说明对名为集合的类的功能的讨论:List
和ArrayList
、Set
和HashSet
以及Map
和HashMap
。我们还将讨论课程Arrays
和ArrayUtils
、Objects
和ObjectUtils
、StringBuilder
和StringBuffer
、LocalDate
、LocalTime
和LocalDateTime
。*