提交 c33c09ea 编写于 作者: W wizardforcel

2020-06-22 20:54:25

上级 1ea38e64
......@@ -104,7 +104,7 @@ java MyApp arg1 arg2
```
数组中的每个字符串称为 _ 命令行参数 _。命令行参数允许用户影响应用程序的操作,而无需重新编译它。例如,排序程序可能允许用户使用此命令行参数指定数据按降序排序:
数组中的每个字符串称为*命令行参数*。命令行参数允许用户影响应用程序的操作,而无需重新编译它。例如,排序程序可能允许用户使用此命令行参数指定数据按降序排序:
```java
-descending
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ops/filter.html](https://docs.oracle.com/javase/tutorial/jndi/ops/filter.html)
除了使用一组属性指定搜索外,您还可以以 _ 搜索过滤器 _ 的形式指定搜索。搜索过滤器是以逻辑表达式的形式表示的搜索查询。 [`DirContext.search()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-java.lang.String-javax.naming.directory.SearchControls-) 接受的搜索过滤器的语法在 [RFC 2254](http://www.ietf.org/rfc/rfc2254.txt) 中描述。
除了使用一组属性指定搜索外,您还可以以*搜索过滤器*的形式指定搜索。搜索过滤器是以逻辑表达式的形式表示的搜索查询。 [`DirContext.search()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-java.lang.String-javax.naming.directory.SearchControls-) 接受的搜索过滤器的语法在 [RFC 2254](http://www.ietf.org/rfc/rfc2254.txt) 中描述。
以下搜索过滤器指定限定条目必须具有`“sn”`属性,其值为`“Geisel”``“mail”`属性,具有任何值:
......@@ -58,9 +58,9 @@ value: +1 408 555 5252
| 符号 | 描述 |
| --- | --- |
| &安培; | 连接(即 _ 和 _ - 列表中的所有内容必须为 true) |
| | | 析取(即 _ 或 _ - 一个或多个替代必须为真) |
| ! | 否定(即 _ 而不是 _ - 被否定的项目不得为真) |
| &安培; | 连接(即*和 _ - 列表中的所有内容必须为 true) |
| | | 析取(即*或 _ - 一个或多个替代必须为真) |
| ! | 否定(即*而不是 _ - 被否定的项目不得为真) |
| = | 相等(根据属性的匹配规则) |
| 〜= | 近似相等(根据属性的匹配规则) |
| > = | 大于(根据属性的匹配规则) |
......
......@@ -4,7 +4,7 @@
默认 [`SearchControls`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchControls.html)指定在指定的上下文中执行搜索( [`SearchControls.ONELEVEL_SCOPE`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchControls.html#ONELEVEL_SCOPE))。此默认值用于[搜索过滤器部分](filter.html)的示例中。
除此默认值外,您还可以指定在 _ 整个子树 _ 中执行搜索,或仅在命名对象中执行搜索。
除此默认值外,您还可以指定在*整个子树*中执行搜索,或仅在命名对象中执行搜索。
搜索整个子树搜索命名对象及其所有后代。要使搜索以这种方式运行,请将 [`SearchControls.SUBTREE_SCOPE`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchControls.html#SUBTREE_SCOPE)传递给 [`SearchControls.setSearchScope()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchControls.html#setSearchScope-int-) ,如下所示。
......
......@@ -19,19 +19,19 @@
_ 原因 _:您没有指定要用于初始上下文的实现。具体来说, [`Context.INITIAL_CONTEXT_FACTORY`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY)环境属性未设置为将创建初始上下文的工厂的类名。或者,您没有向程序提供由`Context.INITIAL_CONTEXT_FACTORY`命名的服务提供者的类。
_ 原因*:您没有指定要用于初始上下文的实现。具体来说, [`Context.INITIAL_CONTEXT_FACTORY`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY)环境属性未设置为将创建初始上下文的工厂的类名。或者,您没有向程序提供由`Context.INITIAL_CONTEXT_FACTORY`命名的服务提供者的类。
_ 解决方案 _:将`Context.INITIAL_CONTEXT_FACTORY`环境属性设置为您正在使用的初始上下文实现的类名。有关详细信息,请参见[配置](index.html)部分。
_ 解决方案*:将`Context.INITIAL_CONTEXT_FACTORY`环境属性设置为您正在使用的初始上下文实现的类名。有关详细信息,请参见[配置](index.html)部分。
如果设置了属性,那么确保类名没有错误输入,并且命名的类可用于您的程序(在其类路径中或安装在`jre / lib / ext`目录中 JRE)。 包括 LDAP,COS 命名,DNS 和 RMI 注册表的服务供应器。必须安装所有其他服务供应器并将其添加到执行环境中。
_ 原因 _:服务器不提供由`Context.PROVIDER_URL`环境属性标识的服务器和端口。也许某人已禁用或关闭运行服务器的计算机。或者,您可能错误输入了服务器的名称或端口号。
_ 原因*:服务器不提供由`Context.PROVIDER_URL`环境属性标识的服务器和端口。也许某人已禁用或关闭运行服务器的计算机。或者,您可能错误输入了服务器的名称或端口号。
_ 解决方案 _:检查该端口上是否确实有服务器正在运行,并在必要时重新启动服务器。执行此检查的方式取决于您使用的 LDAP 服务器。通常,可以使用管理控制台或工具来管理服务器。您可以使用该工具验证服务器的状态。
_ 解决方案*:检查该端口上是否确实有服务器正在运行,并在必要时重新启动服务器。执行此检查的方式取决于您使用的 LDAP 服务器。通常,可以使用管理控制台或工具来管理服务器。您可以使用该工具验证服务器的状态。
_ 原因 _:服务器不响应 LDAP v3 连接请求。某些服务器(尤其是公共服务器)无法正确响应 LDAP v3,忽略请求而不是拒绝它们。此外,某些 LDAP v3 服务器在处理 Oracle 的 LDAP 服务供应器自动发送的控件时遇到问题,并且通常会返回特定于服务器的故障代码。
_ 原因*:服务器不响应 LDAP v3 连接请求。某些服务器(尤其是公共服务器)无法正确响应 LDAP v3,忽略请求而不是拒绝它们。此外,某些 LDAP v3 服务器在处理 Oracle 的 LDAP 服务供应器自动发送的控件时遇到问题,并且通常会返回特定于服务器的故障代码。
_ 解决方案 _。尝试将环境属性`“java.naming.ldap.version”`设置为`“2”`。默认情况下,LDAP 服务供应器尝试使用 LDAP v3 连接到 LDAP 服务器;如果失败,则使用 LDAP v2。如果服务器静默忽略 v3 请求,则供应器将假定请求有效。要解决此类服务器,必须显式设置协议版本以确保服务器的正确行为。
_ 解决方案*。尝试将环境属性`“java.naming.ldap.version”`设置为`“2”`。默认情况下,LDAP 服务供应器尝试使用 LDAP v3 连接到 LDAP 服务器;如果失败,则使用 LDAP v2。如果服务器静默忽略 v3 请求,则供应器将假定请求有效。要解决此类服务器,必须显式设置协议版本以确保服务器的正确行为。
如果服务器是 v3 服务器,则在创建初始上下文之前尝试设置以下环境属性:
......@@ -42,13 +42,13 @@ env.put(Context.REFERRAL, "throw");
这将关闭 LDAP 供应器自动发送的控件。 (有关详细信息,请查看 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/index.html)。)
_ 原因 _:如果您尝试执行会产生太多结果或需要服务器检查太多的搜索,某些服务器(尤其是公共服务器)将不会响应(即使是否定答案)条目以生成答案。这些服务器试图限制它们在每个请求的基础上花费的资源量。
_ 原因*:如果您尝试执行会产生太多结果或需要服务器检查太多的搜索,某些服务器(尤其是公共服务器)将不会响应(即使是否定答案)条目以生成答案。这些服务器试图限制它们在每个请求的基础上花费的资源量。
或者,您尝试对不支持它的服务器/端口使用安全套接字层(SSL),反之亦然(也就是说,您尝试使用普通套接字与 SSL 端口通信)。
最后,由于负载过重或者由于某种原因根本没有响应,服务器要么响应得非常慢。
_ 解决方案 _:如果您的程序因服务器试图限制其资源的使用而挂起,请使用将返回单个结果或仅返回少量结果的查询重试您的请求。这将帮助您确定服务器是否处于活动状态。如果是,那么您可以扩大初始查询并重新提交。
_ 解决方案*:如果您的程序因服务器试图限制其资源的使用而挂起,请使用将返回单个结果或仅返回少量结果的查询重试您的请求。这将帮助您确定服务器是否处于活动状态。如果是,那么您可以扩大初始查询并重新提交。
如果您的程序由于 SSL 问题而挂起,那么您需要确定该端口是否为 SSL 端口,然后适当地设置 [`Context.SECURITY_PROTOCOL`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_PROTOCOL)环境属性。如果端口是 SSL 端口,则此属性应设置为`“ssl”`。如果它不是 SSL 端口,则不应设置此属性。
......@@ -60,26 +60,26 @@ _ 解决方案 _:如果您的程序因服务器试图限制其资源的使用
_ 原因 _:初始化 LDAP 的初始上下文时,提供了根区别的名称。例如,如果将初始上下文的`Context.PROVIDER_URL`环境属性设置为`“ldap:// ldapserver:389 / o = JNDITutorial”`,并随后提供名称,如`“cn = Joe,c = us”`,然后传递给 LDAP 服务的全名是`“cn = Joe,c = us,o = JNDITutorial”`。如果这确实是您想要的名称,那么您应该检查您的服务器以确保它包含这样的条目。
_ 原因*:初始化 LDAP 的初始上下文时,提供了根区别的名称。例如,如果将初始上下文的`Context.PROVIDER_URL`环境属性设置为`“ldap:// ldapserver:389 / o = JNDITutorial”`,并随后提供名称,如`“cn = Joe,c = us”`,然后传递给 LDAP 服务的全名是`“cn = Joe,c = us,o = JNDITutorial”`。如果这确实是您想要的名称,那么您应该检查您的服务器以确保它包含这样的条目。
此外,如果您提供不正确的可分辨名称以进行身份​​验证,Oracle Directory Server 将返回此错误。例如,如果将 [`Context.SECURITY_PRINCIPAL`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL)环境属性设置为`,则 LDAP 供应器将抛出 [`NameNotFoundException`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameNotFoundException.html)“cn = Admin,o =教程“`和`”cn = Admin,o = Tutorial“`不是 LDAP 服务器上的条目。实际返回的 Oracle Directory Server 的正确错误应该是与身份验证相关的内容,而不是“找不到名称”。
_ 解决方案 _:验证您提供的名称是服务器上存在的条目的名称。您可以通过列出条目的父上下文或使用其他工具(如目录服务器的管理控制台)来执行此操作。
_ 解决方案*:验证您提供的名称是服务器上存在的条目的名称。您可以通过列出条目的父上下文或使用其他工具(如目录服务器的管理控制台)来执行此操作。
* * *
以下是尝试部署使用 JNDI 类的 applet 时可能遇到的一些问题。
_ 原因 _:您的 applet 未签名,因此它只能连接到加载它的机器。或者,如果 applet 已签名,则浏览器尚未授予 applet 连接到目录服务器计算机的权限。
_ 原因*:您的 applet 未签名,因此它只能连接到加载它的机器。或者,如果 applet 已签名,则浏览器尚未授予 applet 连接到目录服务器计算机的权限。
_ 解决方案 _:如果你想允许 applet 连接到在任意机器上运行的目录服务器,那么你需要你的 applet _ 和 _ 签署所有 JNDI 您的 applet 将使用的 JAR。有关签名 jar 的信息,请参阅[签名和验证 JAR 文件](../../deployment/jar/signindex.html)
_ 解决方案*:如果你想允许 applet 连接到在任意机器上运行的目录服务器,那么你需要你的 applet _ 和*签署所有 JNDI 您的 applet 将使用的 JAR。有关签名 jar 的信息,请参阅[签名和验证 JAR 文件](../../deployment/jar/signindex.html)。
_ 原因 _:Web 浏览器限制对系统属性的访问,如果您尝试读取它们,则抛出`SecurityException`
_ 原因*:Web 浏览器限制对系统属性的访问,如果您尝试读取它们,则抛出`SecurityException` 。
_ 解决方案 _:如果您需要获取 applet 的输入,请尝试使用 applet params。
_ 解决方案*:如果您需要获取 applet 的输入,请尝试使用 applet params。
_ 原因 _:Firefox 禁止访问`java.security`软件包。 LDAP 供应器使用`java.security.MessageDigest`提供的消息摘要功能来实现 CRAM-MD5。
_ 原因*:Firefox 禁止访问`java.security`软件包。 LDAP 供应器使用`java.security.MessageDigest`提供的消息摘要功能来实现 CRAM-MD5。
_ 解决方案 _:使用 Java Plug-in。
_ 解决方案*:使用 Java Plug-in。
* * *
\ No newline at end of file
......@@ -6,9 +6,9 @@
## LDAP
X.500 是目录服务的 CCITT 标准,是 OSI 服务套件的一部分。 X.500 标准定义了一个协议(以及其他),以便客户端应用程序访问称为 _ 目录访问协议 _(DAP)的 X.500 目录。它位于开放系统互连(OSI)协议栈之上。
X.500 是目录服务的 CCITT 标准,是 OSI 服务套件的一部分。 X.500 标准定义了一个协议(以及其他),以便客户端应用程序访问称为*目录访问协议*(DAP)的 X.500 目录。它位于开放系统互连(OSI)协议栈之上。
互联网社区认识到需要类似 X.500 的服务,但面对不同的底层网络基础设施(TCP / IP 而不是 OSI),设计了一种基于 X.500 DAP 协议的新协议,称为 _Lightweight_ DAP 或 LDAP。 [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) 定义了现在称为 _ 版本 3_ 的 LDAP(或 LDAP v3),它是 [RFC 1777](http://www.ietf.org/rfc/rfc1777.txt) 中指定的其前身 LDAP v2 的改进版本。
互联网社区认识到需要类似 X.500 的服务,但面对不同的底层网络基础设施(TCP / IP 而不是 OSI),设计了一种基于 X.500 DAP 协议的新协议,称为 _Lightweight_ DAP 或 LDAP。 [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) 定义了现在称为*版本 3_ 的 LDAP(或 LDAP v3),它是 [RFC 1777](http://www.ietf.org/rfc/rfc1777.txt) 中指定的其前身 LDAP v2 的改进版本。
LDAP 的目标是一个可以轻松实现的协议,特别注重能够构建小而简单的客户端。它试图实现简化的一种方法是使用大量字符串并尽可能减少结构的使用。例如,DN 在协议中表示为字符串,属性类型名称和许多属性值也是如此。
......@@ -16,4 +16,4 @@ LDAP 的目标是一个可以轻松实现的协议,特别注重能够构建小
由于专注于客户端,LDAP 社区还定义了 DN 的字符串表示( [RFC 2553](http://www.ietf.org/rfc/rfc2553.txt) ),搜索过滤器( [RFC 1960](http://www.ietf.org/rfc/rfc1960.txt) )和属性语法([)的标准。 RFC 1778](http://www.ietf.org/rfc/rfc1778.txt) ),用于基于 C 语言的 API( [RFC 1823](http://www.ietf.org/rfc/rfc1823.txt) ),以及用于访问 LDAP 服务的 URL 格式( [RFC 1959](http://www.ietf.org/rfc/rfc1959.txt) )。
LDAP v3 支持国际化,各种身份验证机制,引用和通用部署机制。它允许将新功能添加到协议中,而无需通过使用 _ 扩展 _ 和 _ 控件 _ 来更改协议。
\ No newline at end of file
LDAP v3 支持国际化,各种身份验证机制,引用和通用部署机制。它允许将新功能添加到协议中,而无需通过使用*扩展**控件*来更改协议。
\ No newline at end of file
......@@ -14,7 +14,7 @@
## 介绍人
_ 推荐 _ 是服务器发送回客户端的信息,指示可以在另一个位置(可能在另一个服务器处)找到所请求的信息。在 LDAP v2 中,服务器应该处理引用而不是将它们返回给客户端。这是因为处理引用可能非常复杂,因此会导致更复杂的客户端。在构建和部署服务器时,发现引用很有用,但没有多少服务器支持服务器端引用处理。因此,我们找到了一种方法来改进协议以允许它返回引用。这是通过将引用置于“部分结果”错误响应的错误消息内部来完成的。
_ 推荐*是服务器发送回客户端的信息,指示可以在另一个位置(可能在另一个服务器处)找到所请求的信息。在 LDAP v2 中,服务器应该处理引用而不是将它们返回给客户端。这是因为处理引用可能非常复杂,因此会导致更复杂的客户端。在构建和部署服务器时,发现引用很有用,但没有多少服务器支持服务器端引用处理。因此,我们找到了一种方法来改进协议以允许它返回引用。这是通过将引用置于“部分结果”错误响应的错误消息内部来完成的。
LDAP v3 明确支持引用,并允许服务器将引用直接返回给客户端。本课不会介绍推荐,但您可以随时参考 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/referral/index.html)来管理应用程序中的推荐。
......@@ -22,18 +22,18 @@ LDAP v3 明确支持引用,并允许服务器将引用直接返回给客户端
诸如 LDAP 之类的通用协议对于确保所有目录客户端和服务器“使用相同的语言”非常有用。当在网络中部署许多不同的目录客户端应用程序和目录服务器时,对于所有这些实体来说,讨论相同的对象也非常有用。
_ 目录模式 _ 指定了目录可能具有的对象类型以及每种类型的对象可能具有的强制和可选属性。 LDAP v3 定义了基于 X.500 标准的模式( [RFC 2252](http://www.ietf.org/rfc/rfc2252.txt)[RFC 2256](http://www.ietf.org/rfc/rfc2256.txt) ),用于网络中的常见对象,例如国家,地区,组织,用户/人员,团体和设备。它还为客户端应用程序定义了一种访问服务器模式的方法,以便它可以找出特定服务器支持的对象类型和属性。
_ 目录模式*指定了目录可能具有的对象类型以及每种类型的对象可能具有的强制和可选属性。 LDAP v3 定义了基于 X.500 标准的模式( [RFC 2252](http://www.ietf.org/rfc/rfc2252.txt)[RFC 2256](http://www.ietf.org/rfc/rfc2256.txt) ),用于网络中的常见对象,例如国家,地区,组织,用户/人员,团体和设备。它还为客户端应用程序定义了一种访问服务器模式的方法,以便它可以找出特定服务器支持的对象类型和属性。
LDAP v3 进一步定义了一组用于表示属性值的语法( [RFC 2252](http://www.ietf.org/rfc/rfc2252.txt) )。要编写需要访问模式的 Java 应用程序,请参阅 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/schema/index.html)
## 扩展
除了预定义操作的所有操作(例如“搜索”和“修改”)之外,LDAP v3 还定义了 _“扩展”操作 _。 “扩展”操作将请求作为参数并返回响应。该请求包含标识请求和请求参数的标识符。响应包含执行请求的结果。这对“扩展”操作请求/响应称为 _ 扩展 _。例如,Start TLS 可以有一个扩展,它是客户端向服务器请求激活 Start TLS 协议的请求。
除了预定义操作的所有操作(例如“搜索”和“修改”)之外,LDAP v3 还定义了*“扩展”操作*。 “扩展”操作将请求作为参数并返回响应。该请求包含标识请求和请求参数的标识符。响应包含执行请求的结果。这对“扩展”操作请求/响应称为*扩展*。例如,Start TLS 可以有一个扩展,它是客户端向服务器请求激活 Start TLS 协议的请求。
这些扩展可以是标准的(由 LDAP 社区定义)或专有的(由特定目录供应商定义)。有关编写需要使用 Extensions 的应用程序,请参阅 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/ext/index.html)
## 控制
添加新功能的另一种方法是使用 _ 控件 _。 LDAP v3 允许通过使用控件修改任何操作的行为。可以与操作一起发送任意数量的控件,并且可以返回任何数量的控件及其结果。例如,您可以发送排序控件以及“搜索”操作,该操作告诉服务器根据`“名称”`属性对搜索结果进行排序。
添加新功能的另一种方法是使用*控件*。 LDAP v3 允许通过使用控件修改任何操作的行为。可以与操作一起发送任意数量的控件,并且可以返回任何数量的控件及其结果。例如,您可以发送排序控件以及“搜索”操作,该操作告诉服务器根据`“名称”`属性对搜索结果进行排序。
与扩展类似,此类控件可以是标准的或专有的。标准控件在[平台](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/Control.html)中提供。有关编写需要使用控件的应用程序,请参阅 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/ext/index.html)
\ No newline at end of file
......@@ -26,6 +26,6 @@ cn=Vinnie Ryan, ou=People, o=JNDITutorial
```
但是,在 JNDI 中,名称始终是 _ 相对 _;也就是说,您总是相对于上下文命名对象。例如,您可以将条目`“cn = Vinnie Ryan”`命名为相对于名为`“ou = People,o = JNDITutorial”`的上下文。或者你可以命名条目`“cn = Vinnie Ryan,ou = People”`相对于名为`“o = JNDITutorial”`的上下文。或者,您可以创建指向 LDAP 服务器命名空间根目录的初始上下文,并将条目命名为`“cn = Vinnie Ryan,ou = People,o = JNDITutorial”`
但是,在 JNDI 中,名称始终是*相对 _;也就是说,您总是相对于上下文命名对象。例如,您可以将条目`“cn = Vinnie Ryan”`命名为相对于名为`“ou = People,o = JNDITutorial”`的上下文。或者你可以命名条目`“cn = Vinnie Ryan,ou = People”`相对于名为`“o = JNDITutorial”`的上下文。或者,您可以创建指向 LDAP 服务器命名空间根目录的初始上下文,并将条目命名为`“cn = Vinnie Ryan,ou = People,o = JNDITutorial”`
在 JNDI 中,您还可以使用 LDAP URL 命名 LDAP 条目。请参阅 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/misc/url.html)中的 LDAP URL 讨论。
\ No newline at end of file
......@@ -11,7 +11,7 @@ byte mask = 0xff;
```
但是,有理由使用对象代替基元,Java 平台为每种基本数据类型提供 _ 包装器 _ 类。这些类将对象“包装”在对象中。通常,包装是由编译器完成的 - 如果你使用一个需要一个对象的原始,编译器 _ 就会在你的包装类中为 _ 包装原始。类似地,如果在期望基元时使用数字对象,编译器 _ 会为您取消 _ 对象。有关更多信息,请参阅 [Autoboxing 和 Unboxing](autoboxing.html)
但是,有理由使用对象代替基元,Java 平台为每种基本数据类型提供*包装器*类。这些类将对象“包装”在对象中。通常,包装是由编译器完成的 - 如果你使用一个需要一个对象的原始,编译器*就会在你的包装类中为*包装原始。类似地,如果在期望基元时使用数字对象,编译器*会为您取消*对象。有关更多信息,请参阅 [Autoboxing 和 Unboxing](autoboxing.html)
所有数字包装类都是抽象类`Number`的子类:
......
......@@ -4,7 +4,7 @@
LDAP 服务提供通用目录服务。它可以用来存储各种信息。所有 LDAP 服务器都有一些系统用于控制谁可以读取和更新目录中的信息。
要访问 LDAP 服务,LDAP 客户端首先必须 _ 向服务验证 _ 本身。也就是说,它必须告诉 LDAP 服务器谁将访问数据,以便服务器可以决定允许客户端查看和执行的操作。如果客户端成功验证 LDAP 服务器,则当服务器随后从客户端收到请求时,它将检查是否允许客户端执行请求。该过程称为 _ 访问控制 _
要访问 LDAP 服务,LDAP 客户端首先必须*向服务验证*本身。也就是说,它必须告诉 LDAP 服务器谁将访问数据,以便服务器可以决定允许客户端查看和执行的操作。如果客户端成功验证 LDAP 服务器,则当服务器随后从客户端收到请求时,它将检查是否允许客户端执行请求。该过程称为*访问控制*
LDAP 标准提出了 LDAP 客户端可以对 LDAP 服务器进行身份验证的方法( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt)[RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) )。这些在 [LDAP 认证部分](authentication.html)[认证机制部分](auth_mechs.html)中进行了一般性讨论。本课程还包含如何使用[匿名](anonymous.html)[简单](simple.html)[SASL](sasl.html) 认证机制的说明。
......
......@@ -4,9 +4,9 @@
在 LDAP 中,身份验证信息在“绑定”操作中提供。在 LDAP v2 中,客户端通过向服务器发送包含身份验证信息的“绑定”操作来启动与 LDAP 服务器的连接。
在 LDAP v3 中,此操作用于相同的目的,但它是可选的。发送 LDAP 请求而不执行“绑定”的客户端被视为 _ 匿名 _ 客户端(有关详细信息,请参阅[匿名](anonymous.html)部分)。在 LDAP v3 中,“绑定”操作可以在连接期间的任何时间发送,可能不止一次。客户端可以在连接中间发送“绑定”请求以更改其标识。如果请求成功,则丢弃在连接上使用旧标识的所有未完成请求,并且连接与新标识关联。
在 LDAP v3 中,此操作用于相同的目的,但它是可选的。发送 LDAP 请求而不执行“绑定”的客户端被视为*匿名*客户端(有关详细信息,请参阅[匿名](anonymous.html)部分)。在 LDAP v3 中,“绑定”操作可以在连接期间的任何时间发送,可能不止一次。客户端可以在连接中间发送“绑定”请求以更改其标识。如果请求成功,则丢弃在连接上使用旧标识的所有未完成请求,并且连接与新标识关联。
“绑定”操作中提供的认证信息取决于客户端选择的 _ 认证机制 _。有关身份验证机制的讨论,请参阅[身份验证机制](auth_mechs.html)
“绑定”操作中提供的认证信息取决于客户端选择的*认证机制*。有关身份验证机制的讨论,请参阅[身份验证机制](auth_mechs.html)
## 使用 JNDI 对 LDAP 进行身份验证
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ldap/anonymous.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/anonymous.html)
如上所述,如果未设置认证环境属性,则默认认证机制为`“无”`。如果客户端将 [`Context.SECURITY_AUTHENTICATION`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_AUTHENTICATION)环境属性设置为`“无”`,则认证机制为`“无”`和所有其他身份验证环境属性被忽略。您可能希望仅显式执行此操作,以确保忽略可能已设置的任何其他身份验证属性。在任何一种情况下,客户端都将被视为 _ 匿名 _ 客户端。这意味着服务器不知道或不关心客户端是谁,并且将允许客户端访问(读取和更新)任何已配置为可由任何未经身份验证的客户端访问的数据。
如上所述,如果未设置认证环境属性,则默认认证机制为`“无”`。如果客户端将 [`Context.SECURITY_AUTHENTICATION`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_AUTHENTICATION)环境属性设置为`“无”`,则认证机制为`“无”`和所有其他身份验证环境属性被忽略。您可能希望仅显式执行此操作,以确保忽略可能已设置的任何其他身份验证属性。在任何一种情况下,客户端都将被视为*匿名*客户端。这意味着服务器不知道或不关心客户端是谁,并且将允许客户端访问(读取和更新)任何已配置为可由任何未经身份验证的客户端访问的数据。
由于[命名和目录操作](../ops/index.html)课程中的任何目录示例都没有设置任何身份验证环境属性,因此所有这些都使用匿名身份验证。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ldap/simple.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/simple.html)
_ 简单 _ 认证包括向 LDAP 服务器发送客户端(用户)的完全限定 DN 和客户端的明文密码(参见 [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt)[RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) )。此机制存在安全问题,因为可以从网络读取密码。为避免以这种方式暴露密码,您可以在加密通道(如 SSL)中使用简单身份验证机制,前提是 LDAP 服务器支持此功能。
_ 简单*认证包括向 LDAP 服务器发送客户端(用户)的完全限定 DN 和客户端的明文密码(参见 [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt)[RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) )。此机制存在安全问题,因为可以从网络读取密码。为避免以这种方式暴露密码,您可以在加密通道(如 SSL)中使用简单身份验证机制,前提是 LDAP 服务器支持此功能。
LDAP v2 和 v3 都支持简单身份验证。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ldap/sasl.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/sasl.html)
LDAP v3 协议使用 [SASL](http://www.ietf.org/rfc/rfc2222.txt) 来支持 _ 可插拔 _ 身份验证。这意味着 LDAP 客户端和服务器可以配置为协商并使用可能的非标准和/或自定义机制进行身份验证,具体取决于客户端和服务器所需的保护级别。 LDAP v2 协议不支持 SASL。
LDAP v3 协议使用 [SASL](http://www.ietf.org/rfc/rfc2222.txt) 来支持*可插拔*身份验证。这意味着 LDAP 客户端和服务器可以配置为协商并使用可能的非标准和/或自定义机制进行身份验证,具体取决于客户端和服务器所需的保护级别。 LDAP v2 协议不支持 SASL。
目前定义了几种 SASL 机制:
......@@ -72,4 +72,4 @@ env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");
[Digest-MD5 示例](digest.html)显示如何使用`Context.SECURITY_PRINCIPAL``Context.SECURITY_CREDENTIALS`属性进行 Digest-MD5 身份验证。
如果机制需要输入而不是已经描述的那些,那么你需要为要使用的机制定义 _ 回调 _ 对象,你可以查看 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/callback.html)中的回调示例。本课程的下一部分将讨论如何使用 SASL Digest-MD5 身份验证机制。 JNDI 教程中介绍了 [SASL 策略](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/sasl.html)[GSS API(Kerberos v5)](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/gssapi.html)[CRAM-MD5](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/crammd5.html) 机制。
\ No newline at end of file
如果机制需要输入而不是已经描述的那些,那么你需要为要使用的机制定义*回调*对象,你可以查看 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/callback.html)中的回调示例。本课程的下一部分将讨论如何使用 SASL Digest-MD5 身份验证机制。 JNDI 教程中介绍了 [SASL 策略](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/sasl.html)[GSS API(Kerberos v5)](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/gssapi.html)[CRAM-MD5](https://docs.oracle.com/javase/jndi/tutorial/ldap/security/crammd5.html) 机制。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ldap/digest.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/digest.html)
_Digest-MD5 身份验证 _ 是 LDAP v3 服务器( [RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) )所需的身份验证机制。由于 SASL 的使用是 LDAP v3( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) )的一部分,因此仅支持 LDAP v2 的服务器不支持 Digest-MD5。
_Digest-MD5 身份验证*是 LDAP v3 服务器( [RFC 2829](http://www.ietf.org/rfc/rfc2829.txt) )所需的身份验证机制。由于 SASL 的使用是 LDAP v3( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) )的一部分,因此仅支持 LDAP v2 的服务器不支持 Digest-MD5。
Digest-MD5 机制在 [RFC 2831](http://www.ietf.org/rfc/rfc2831.txt) 中描述。它基于 HTTP 摘要认证( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) )。在 Digest-MD5 中,LDAP 服务器将包含其愿意支持的各种身份验证选项的数据以及特殊令牌发送到 LDAP 客户端。客户端通过发送加密响应来响应,该响应指示它已选择的身份验证选项。响应以这样的方式加密,以证明客户端知道其密码。然后,LDAP 服务器解密并验证客户端的响应。
......@@ -49,7 +49,7 @@ DirContext ctx = new InitialDirContext(env);
## 指定域
_ 域 _ 定义名称空间,从中选择认证实体( `Context.SECURITY_PRINCIPAL`属性的值))。服务器可能有多个域。例如,大学的服务器可能被配置为具有两个域,一个用于其学生用户,另一个用于教师用户。域配置由目录管理员完成。某些目录具有默认的单个域。例如,Oracle Directory Server v5.2 使用计算机的标准主机名作为默认域。
_ 域*定义名称空间,从中选择认证实体( `Context.SECURITY_PRINCIPAL`属性的值))。服务器可能有多个域。例如,大学的服务器可能被配置为具有两个域,一个用于其学生用户,另一个用于教师用户。域配置由目录管理员完成。某些目录具有默认的单个域。例如,Oracle Directory Server v5.2 使用计算机的标准主机名作为默认域。
在 Digest-MD5 身份验证中,您必须对特定域进行身份验证。您可以使用以下身份验证环境属性来指定域。如果未指定域,则将使用服务器提供的任何域。
......
......@@ -54,7 +54,7 @@ DirContext ctx = new InitialDirContext(env);
* * *
**注意:**如果您使用 SSL 连接到 _ 而不是 _ 的端口上的服务器使用 SSL,那么您的程序将挂起。同样,如果您使用普通套接字连接到服务器的 SSL 套接字,那么您的应用程序将挂起。这是 SSL 协议的特征。
**注意:**如果您使用 SSL 连接到*而不是*的端口上的服务器使用 SSL,那么您的程序将挂起。同样,如果您使用普通套接字连接到服务器的 SSL 套接字,那么您的应用程序将挂起。这是 SSL 协议的特征。
* * *
......
......@@ -9,7 +9,7 @@ LDAP“比较”操作允许客户端询问服务器命名条目是否具有属
* [`搜索(名称,字符串过滤器,SearchControls ctls)`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-java.lang.String-javax.naming.directory.SearchControls-)
* [`搜索(名称名称,String filterExpr,Object [] filterArgs,SearchControls ctls)`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-java.lang.String-java.lang.Object:A-javax.naming.directory.SearchControls-)
1. 过滤器必须是“(_ 名称 _ = _ 值 _)”的形式。你不能使用外卡。
1. 过滤器必须是“(*名称 _ = _ 值*)”的形式。你不能使用外卡。
2. 搜索范围必须是 [`SearchControls.OBJECT_SCOPE`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchControls.html#OBJECT_SCOPE)
3. 您必须请求不返回任何属性。如果不满足这些条件,则这些方法将使用 LDAP“搜索”操作而不是 LDAP“比较”操作。
......
......@@ -29,9 +29,9 @@ System.out.format("The value of " + "the float variable is " +
```
第一个参数`format`是一个格式字符串,指定如何格式化第二个参数`args`中的对象。格式字符串包含纯文本以及 _ 格式说明符 _,它们是格式化`Object... args`参数的特殊字符。 (符号`Object... args`称为 _varargs_ ,这意味着参数的数量可能会有所不同。)
第一个参数`format`是一个格式字符串,指定如何格式化第二个参数`args`中的对象。格式字符串包含纯文本以及*格式说明符*,它们是格式化`Object... args`参数的特殊字符。 (符号`Object... args`称为 _varargs_ ,这意味着参数的数量可能会有所不同。)
格式说明符以百分号(%)开头,以 _ 转换器 _ 结束。转换器是一个字符,指示要格式化的参数类型。在百分号(%)和转换器之间,您可以使用可选的标志和说明符。有许多转换器,标志和说明符,在 [`java.util.Formatter`](https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html) 中有记录
格式说明符以百分号(%)开头,以*转换器*结束。转换器是一个字符,指示要格式化的参数类型。在百分号(%)和转换器之间,您可以使用可选的标志和说明符。有许多转换器,标志和说明符,在 [`java.util.Formatter`](https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html) 中有记录
这是一个基本的例子:
......
......@@ -9,7 +9,7 @@
* [类名称](#CLASS)
* [属性](#ATTRS)
每个`SearchResult`都包含满足搜索过滤器的 LDAP 条目的名称。您可以使用 [`getName()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameClassPair.html#getName--) 获取条目的名称。该方法将[条目 _ 相对 _ 的 [`复合名称`](https://docs.oracle.com/javase/8/docs/api/javax/naming/CompositeName.html) 返回到 _ 目标上下文 _。目标上下文是`名称`参数解析的上下文。在 LDAP 用语中,目标上下文是搜索的 _ 基础对象 _。这是一个例子。
每个`SearchResult`都包含满足搜索过滤器的 LDAP 条目的名称。您可以使用 [`getName()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameClassPair.html#getName--) 获取条目的名称。该方法将[条目*相对*的 [`复合名称`](https://docs.oracle.com/javase/8/docs/api/javax/naming/CompositeName.html) 返回到*目标上下文*。目标上下文是`名称`参数解析的上下文。在 LDAP 用语中,目标上下文是搜索的*基础对象*。这是一个例子。
```java
NamingEnumeration answer = ctx.search("ou=NewHires",
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/ldap/unsol.html](https://docs.oracle.com/javase/tutorial/jndi/ldap/unsol.html)
LDAP v3( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) )定义 _ 未经请求的通知 _,该消息由 LDAP 服务器发送到客户端,而不会从客户端进行任何激发。未经请求的通知由 [`UnsolicitedNotification`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/UnsolicitedNotification.html)接口在 JNDI 中表示。
LDAP v3( [RFC 2251](http://www.ietf.org/rfc/rfc2251.txt) )定义*未经请求的通知*,该消息由 LDAP 服务器发送到客户端,而不会从客户端进行任何激发。未经请求的通知由 [`UnsolicitedNotification`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/UnsolicitedNotification.html)接口在 JNDI 中表示。
由于服务器异步发送未经请求的通知,因此您可以使用相同的[事件模型](https://docs.oracle.com/javase/jndi/tutorial/beyond/event/index.html)来接收有关命名空间更改和对象内容更改的通知。您通过注册 [`UnsolicitedNotificationListener`](https://docs.oracle.com/javase/8/docs/api/javax/naming/ldap/UnsolicitedNotificationListener.html)[`EventContext`](https://docs.oracle.com/javase/8/docs/api/javax/naming/event/EventContext.html)[`EventDirContext`注册接收未经请求的通知的兴趣 HTG13]。](https://docs.oracle.com/javase/8/docs/api/javax/naming/event/EventDirContext.html)
......
......@@ -4,7 +4,7 @@
创建连接时描述[连接创建](create.html)部分。它描述了几个`Context`实例如何共享同一个连接。
LDAP 服务提供商支持的另一种连接共享称为 _ 连接池 _。在这种类型的共享中,LDAP 服务提供者维护一个(可能)先前使用的连接池,并根据需要将它们分配给`Context`实例。当`Context`实例完成连接(关闭或垃圾收集)时,连接将返回到池中以供将来使用。请注意,这种共享形式是顺序的:从池中检索连接,使用,返回到池,然后再从池中检索另一个`Context`实例。
LDAP 服务提供商支持的另一种连接共享称为*连接池*。在这种类型的共享中,LDAP 服务提供者维护一个(可能)先前使用的连接池,并根据需要将它们分配给`Context`实例。当`Context`实例完成连接(关闭或垃圾收集)时,连接将返回到池中以供将来使用。请注意,这种共享形式是顺序的:从池中检索连接,使用,返回到池,然后再从池中检索另一个`Context`实例。
每个 Java 运行时系统都维护连接池。在某些情况下,连接池可以显着提高性能。例如,如果使用连接池,则只需要一个连接来处理包含对同一 LDAP 服务器的四个引用引用的搜索响应。如果没有连接池,这种情况将需要四个单独的连接。
......@@ -61,7 +61,7 @@ Release com.sun.jndi.ldap.LdapClient@5d173
```
您可以通过包含或省略`“com.sun.jndi.ldap.connect.pool”`属性来决定何时何地使用池,从而控制 _ 每个上下文 _ 的池化基础。在前面的示例中,如果在创建第二个初始上下文之前从环境属性中删除了此属性,则第二个初始上下文将不使用池化连接。
您可以通过包含或省略`“com.sun.jndi.ldap.connect.pool”`属性来决定何时何地使用池,从而控制*每个上下文*的池化基础。在前面的示例中,如果在创建第二个初始上下文之前从环境属性中删除了此属性,则第二个初始上下文将不使用池化连接。
LDAP 供应器通过应用程序的指示跟踪是否正在使用连接。它假定维护打开的上下文句柄的应用程序正在使用该连接。因此,为了使 LDAP 供应器能够正确管理池化连接,您必须努力在不再需要的上下文中调用`Context.close()`
......
......@@ -4,7 +4,7 @@
每个 Java 运行时配置和维护连接池。不在不同的运行时间之间共享连接。要使用连接池,不需要进行任何配置。仅当您要自定义池的完成方式时才需要进行配置,例如控制池的大小以及池的连接类型。
您可以在程序启动时使用许多系统属性来配置连接池。请注意,这些是系统属性,_ 而不是 _ 环境属性,它们会影响所有连接池请求。
您可以在程序启动时使用许多系统属性来配置连接池。请注意,这些是系统属性,*而不是*环境属性,它们会影响所有连接池请求。
下面是一个命令行示例,它将最大池大小设置为 20,将首选池大小设置为 10,将池空连接的空闲超时设置为分钟。
......@@ -36,7 +36,7 @@
## 如何连接连接
`Context`实例请求使用池连接时,LDAP 供应器需要确定现有池连接是否可以满足请求。它通过为每个池化连接分配 _ 连接标识 _ 并检查传入请求是否具有与其池化连接之一相同的连接标识来实现此目的。
`Context`实例请求使用池连接时,LDAP 供应器需要确定现有池连接是否可以满足请求。它通过为每个池化连接分配*连接标识*并检查传入请求是否具有与其池化连接之一相同的连接标识来实现此目的。
连接标识是创建可能经过身份验证的 LDAP 连接所需的参数集。其组成取决于请求的身份验证类型,如下表所示。
......@@ -97,11 +97,11 @@
LDAP 供应器维护连接池;每个池保存具有相同连接标识的连接(使用中或空闲)。有三种尺寸会影响每个池的管理。这些大小是全局的,会影响所有池。
_ 初始池大小 _ 是 LDAP 服务供应器在首次创建池时创建的每个连接标识的连接数(对应于应用程序首次请求该连接标识的池连接时)。在使用连接时,按需执行池中每个连接的身份验证。默认情况下,初始池大小为 1,可以使用系统属性`“com.sun.jndi.ldap.connect.pool.initsize”`进行更改。它通常在应用程序启动时使用,以通过与服务器的一定数量的连接来填充池。
_ 初始池大小*是 LDAP 服务供应器在首次创建池时创建的每个连接标识的连接数(对应于应用程序首次请求该连接标识的池连接时)。在使用连接时,按需执行池中每个连接的身份验证。默认情况下,初始池大小为 1,可以使用系统属性`“com.sun.jndi.ldap.connect.pool.initsize”`进行更改。它通常在应用程序启动时使用,以通过与服务器的一定数量的连接来填充池。
_ 最大池大小 _ 是 LDAP 服务供应器可以同时维护的每个连接标识的最大连接数。使用中和空闲连接都有助于此数字。当池大小达到该数量时,在删除池中的连接(即,物理连接关闭)之前,不会创建对应连接标识的新连接。当池大小达到最大值并且池中的所有连接都在使用时,应用程序对该池中连接的请求将被阻止,直到池中的连接变为空闲或被删除。最大池大小为 0 表示没有最大大小:池连接请求将使用现有的池空闲连接或新创建的池连接。
_ 最大池大小*是 LDAP 服务供应器可以同时维护的每个连接标识的最大连接数。使用中和空闲连接都有助于此数字。当池大小达到该数量时,在删除池中的连接(即,物理连接关闭)之前,不会创建对应连接标识的新连接。当池大小达到最大值并且池中的所有连接都在使用时,应用程序对该池中连接的请求将被阻止,直到池中的连接变为空闲或被删除。最大池大小为 0 表示没有最大大小:池连接请求将使用现有的池空闲连接或新创建的池连接。
_ 首选池大小 _ 是 LDAP 服务提供商应维护的每个连接标识的首选连接数。使用中和空闲连接都有助于此数字。当应用程序请求使用池连接且池大小小于首选大小时,无论空闲连接是否可用,LDAP 供应器都将创建并使用新的池连接。当应用程序完成池化连接(通过在共享连接的所有上下文上调用`Context.close()`)并且池大小大于首选大小时,LDAP 供应器将关闭并删除从游泳池汇集连接。优选的池大小为 0 意味着没有首选大小:只有在没有空闲连接可用时,对池连接的请求才会导致新创建的连接。
_ 首选池大小*是 LDAP 服务提供商应维护的每个连接标识的首选连接数。使用中和空闲连接都有助于此数字。当应用程序请求使用池连接且池大小小于首选大小时,无论空闲连接是否可用,LDAP 供应器都将创建并使用新的池连接。当应用程序完成池化连接(通过在共享连接的所有上下文上调用`Context.close()`)并且池大小大于首选大小时,LDAP 供应器将关闭并删除从游泳池汇集连接。优选的池大小为 0 意味着没有首选大小:只有在没有空闲连接可用时,对池连接的请求才会导致新创建的连接。
请注意,最大池大小会覆盖初始池大小和首选池大小。例如,将首选池大小设置为大于最大池大小有效地将其设置为最大池大小。
......
......@@ -41,7 +41,7 @@
* * *
答案取决于实现。这是因为 [`Context`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html)[`DirContext`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html)接口没有指定同步要求。 JDK 中的 LDAP 实现针对单线程访问进行了优化。如果你有多个线程访问相同的`Context`实例,那么每个线程在使用它时需要锁定`Context`实例。这也适用于从同一`Context`实例派生的任何`NamingEnumeration` 。但是,多个线程可以在没有锁的情况下同时访问 _ 不同的 _ `Context`实例(甚至是那些从相同的初始上下文派生的实例)。
答案取决于实现。这是因为 [`Context`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html)[`DirContext`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html)接口没有指定同步要求。 JDK 中的 LDAP 实现针对单线程访问进行了优化。如果你有多个线程访问相同的`Context`实例,那么每个线程在使用它时需要锁定`Context`实例。这也适用于从同一`Context`实例派生的任何`NamingEnumeration` 。但是,多个线程可以在没有锁的情况下同时访问*不同的 _ `Context`实例(甚至是那些从相同的初始上下文派生的实例)。
[`Context.SECURITY_CREDENTIALS` ](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS)`“java.naming.security,为什么 LDAP 供应器会忽略我的安全环境属性。凭证“`)属性还是将其设置为空字符串?
......@@ -89,7 +89,7 @@ env.put("com.sun.jndi.ldap.trace.ber", System.err);
[`SearchResult` ](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchResult.html)中有一个空字符串作为名称?
[`getName()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameClassPair.html#getName--) 总是将 _ 相对 _ 的名称返回到搜索的 _ 目标上下文 _。因此,如果目标上下文满足搜索过滤器,则返回的名称将为“”(空名称),因为这是相对于目标上下文的名称。有关详细信息,请参阅[搜索结果](result.html)部分。
[`getName()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/NameClassPair.html#getName--) 总是将*相对*的名称返回到搜索的*目标上下文*。因此,如果目标上下文满足搜索过滤器,则返回的名称将为“”(空名称),因为这是相对于目标上下文的名称。有关详细信息,请参阅[搜索结果](result.html)部分。
[`SearchResult` ](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/SearchResult.html)中有一个 URL 字符串作为名称?
......
......@@ -23,7 +23,7 @@
本课程介绍了如何在存储对象后将可序列化对象存储在目录中,您只需使用 [`lookup()`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#lookup-javax.naming.Name-) 从目录中获取对象的副本,无论是实际存储了什么类型的信息。
您不仅可以通过使用`lookup()`来获取对象,还可以在 [`列出`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#list-javax.naming.Name-) 上下文时以及 [`搜索时`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-) 一个上下文或其子树。在所有这些情况下,可能涉及 _ 对象工厂 _。对象工厂在 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/objects/factory/index.html)中有详细讨论。
您不仅可以通过使用`lookup()`来获取对象,还可以在 [`列出`](https://docs.oracle.com/javase/8/docs/api/javax/naming/Context.html#list-javax.naming.Name-) 上下文时以及 [`搜索时`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#search-javax.naming.Name-) 一个上下文或其子树。在所有这些情况下,可能涉及*对象工厂*。对象工厂在 [JNDI 教程](https://docs.oracle.com/javase/jndi/tutorial/objects/factory/index.html)中有详细讨论。
要存储下面的对象类型,请参阅 JNDI 教程:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html](https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html)
对于 _ 序列化 _,对象意味着将其状态转换为字节流,以便可以将字节流还原为对象的副本。 Java 对象是 _serializable_ ,如果它的类或其任何超类实现`java.io.Serializable`接口或其子接口, `java.io.Externalizable` 。 _ 反序列化 _ 是将对象的序列化形式转换回对象副本的过程。
对于*序列化*,对象意味着将其状态转换为字节流,以便可以将字节流还原为对象的副本。 Java 对象是 _serializable_ ,如果它的类或其任何超类实现`java.io.Serializable`接口或其子接口, `java.io.Externalizable`*反序列化*是将对象的序列化形式转换回对象副本的过程。
例如, `java.awt.Button`类实现`Serializable`接口,因此您可以序列化`java.awt.Button`对象并将该序列化状态存储在一份文件。稍后,您可以回读序列化状态并反序列化为`java.awt.Button`对象。
......@@ -52,7 +52,7 @@ java.awt.Button[button0,0,0,0x0,invalid,label=Push me]
当序列化对象绑定在目录中时,如上例所示,从目录中读取序列化对象的应用程序必须能够访问反序列化对象所需的类定义。
或者,您可以在绑定对象时或者通过使用 [`DirContext.modifyAttributes`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#modifyAttributes-javax.naming.Name-int-javax.naming.directory.Attributes-) 添加属性时,在目录中记录带有序列化对象的 _ 代码库 _。您可以使用任何属性来记录此代码库,并让您的应用程序从目录中读取该属性并正确使用它。或者您可以使用指定的`“javaCodebase”`属性。在后一种情况下,Oracle 的 LDAP 服务供应器将根据需要自动使用该属性加载类定义。 `“javaCodebase”`应该包含代码库目录或 JAR 文件的 URL。如果代码库包含多个 URL,则每个 URL 必须用空格字符分隔。
或者,您可以在绑定对象时或者通过使用 [`DirContext.modifyAttributes`](https://docs.oracle.com/javase/8/docs/api/javax/naming/directory/DirContext.html#modifyAttributes-javax.naming.Name-int-javax.naming.directory.Attributes-) 添加属性时,在目录中记录带有序列化对象的*代码库*。您可以使用任何属性来记录此代码库,并让您的应用程序从目录中读取该属性并正确使用它。或者您可以使用指定的`“javaCodebase”`属性。在后一种情况下,Oracle 的 LDAP 服务供应器将根据需要自动使用该属性加载类定义。 `“javaCodebase”`应该包含代码库目录或 JAR 文件的 URL。如果代码库包含多个 URL,则每个 URL 必须用空格字符分隔。
以下示例类似于绑定`java.awt.Button`的示例。它的不同之处在于它使用了用户定义的`Serializable`类, [``Flower` `](examples/Flower.java),并提供`“javaCodebase”` ]属性包含`Flower`的类定义的位置。这是执行绑定的代码。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/sdp/sockets/index.html](https://docs.oracle.com/javase/tutorial/sdp/sockets/index.html)
对于高性能计算环境,需要快速有效地在网络上移动数据的能力。这种网络通常被描述为需要高吞吐量和低延迟。 _ 高吞吐量 _ 是指可以长时间提供大量处理能力的环境。 _ 低延迟 _ 是指处理输入和提供输出之间的最小延迟,例如您在实时应用程序中所期望的。
对于高性能计算环境,需要快速有效地在网络上移动数据的能力。这种网络通常被描述为需要高吞吐量和低延迟。*高吞吐量*是指可以长时间提供大量处理能力的环境。*低延迟*是指处理输入和提供输出之间的最小延迟,例如您在实时应用程序中所期望的。
在这些环境中,使用套接字流的传统网络在移动数据时可能会产生瓶颈。 InfiniBand(IB)于 1999 年由 [InfiniBand 贸易协会](http://www.infinibandta.org/)推出,旨在满足高性能计算的需求。 IB 最重要的特性之一是远程直接内存访问(RDMA)。 RDMA 可以将数据直接从一台计算机的内存移动到另一台计算机,绕过两台计算机的操作系统,从而显着提高性能。
......
......@@ -41,7 +41,7 @@ connect examplecluster.example.com 3306
```
示例文件中的第一条规则指定 SDP 用于本地 IP 地址`192.0.2.1`上的任何端口(*)。您将为分配给 InfiniBand 适配器的每个本地地址添加绑定规则。 ( _InfiniBand 适配器 _ 相当于 InfiniBand 的网络接口卡(NIC)。)如果您有多个 IB 适配器,则可以为分配给这些适配器的每个地址使用绑定规则。
示例文件中的第一条规则指定 SDP 用于本地 IP 地址`192.0.2.1`上的任何端口(*)。您将为分配给 InfiniBand 适配器的每个本地地址添加绑定规则。 ( _InfiniBand 适配器*相当于 InfiniBand 的网络接口卡(NIC)。)如果您有多个 IB 适配器,则可以为分配给这些适配器的每个地址使用绑定规则。
示例文件中的第二条规则指定每当连接到`192.0.2.*`且目标端口为 1024 或更大时,都会使用 SDP。 IP 地址`/24`上的前缀表示 32 位 IP 地址的前 24 位应与指定的地址匹配。 IP 地址的每个部分使用 8 位,因此 24 位表示 IP 地址应与`192.0.2`匹配,最后一个字节可以是任何值。端口令牌上的`-*`表示法指定“及以上”。一系列端口(例如 1024-2056)也是有效的,并且包括指定范围的端点。
......
......@@ -193,7 +193,7 @@ schemagen [-d path]
```
`-d` _ 路径 _ 选项指定处理器生成的和`javac`生成的类文件的位置。
`-d` _ 路径*选项指定处理器生成的和`javac`生成的类文件的位置。
## 关于 Schema-to-Java 绑定
......
......@@ -23,7 +23,7 @@
* 为模式派生的 JAXB 包,类,方法和常量创建 API 文档:通过向模式添加自定义 Javadoc 工具注释,您可以解释特定于实现的概念,指南和规则。
* 为缺省 XML 名称到 Java 标识符映射无法自动处理的情况提供语义上有意义的自定义名称;例如:
* 解决名称冲突(如 _JAXB 规范 _ 的附录 D.2.1 中所述)。请注意,JAXB 绑定编译器会检测并报告所有名称冲突。
* 解决名称冲突(如 _JAXB 规范*的附录 D.2.1 中所述)。请注意,JAXB 绑定编译器会检测并报告所有名称冲突。
* 为非有效 Java 标识符的类型安全枚举常量提供名称;例如,枚举整数值。
* 为绑定到 Java 属性或类的未命名模型组的 Java 表示提供更好的名称。
* 提供比默认情况下从目标命名空间 URI 派生的更有意义的包名。
......@@ -60,7 +60,7 @@
### 内联自定义
通过 XML 模式文件中的内联**绑定声明**进行的 JAXB 绑定的自定义采用`< xsd:appinfo&gt;的形式。嵌入在模式`< xsd:annotation&gt;中的`元素`元素( `xsd:`是 XML 模式名称空间前缀,如 W3C _XML 模式第 1 部分:结构 _ 中所定义)。以下示例显示了内联自定义的一般形式:
通过 XML 模式文件中的内联**绑定声明**进行的 JAXB 绑定的自定义采用`< xsd:appinfo&gt;的形式。嵌入在模式`< xsd:annotation&gt;中的`元素`元素( `xsd:`是 XML 模式名称空间前缀,如 W3C _XML 模式第 1 部分:结构*中所定义)。以下示例显示了内联自定义的一般形式:
```java
<xs:annotation>
......@@ -121,7 +121,7 @@ xjc -b file schema
```
其中 _ 文件 _ 是绑定自定义文件的名称,_ 模式 _ 是您要传递给绑定编译器的模式的名称。
其中*文件*是绑定自定义文件的名称,*模式*是您要传递给绑定编译器的模式的名称。
您可以拥有一个包含多个模式自定义的绑定文件,也可以将自定义分隔为多个绑定文件;例如:
......@@ -403,7 +403,7 @@ xjc schema1.xsd schema2.xsd schema3.xsd \
对于内联注释,`< typesafeEnumClass&gt;必须在`< simpleType&gt;的注释元素中指定`声明。`元素。 `< typesafeEnumMember&gt;必须在枚举成员的注释元素中指定`。这使得枚举成员可以独立于枚举类进行定制。
有关类型安全枚举设计模式的信息,请参阅 Oracle 技术网上 Joshua Bloch _ 有效 Java 编程 _ [示例章节。](http://www.oracle.com/technetwork/java/page1-139488.html)
有关类型安全枚举设计模式的信息,请参阅 Oracle 技术网上 Joshua Bloch _ 有效 Java 编程*[示例章节。](http://www.oracle.com/technetwork/java/page1-139488.html)
### javadoc 绑定声明
......
......@@ -13,7 +13,7 @@ char[] charArray = { 'a', 'b', 'c', 'd', 'e' };
```
但是,有时候需要使用 char 作为对象 - 例如,作为期望对象的方法参数。 Java 编程语言提供了一个 _ 包装器 _ 类,为此目的“包装”`Character`对象中的`char``Character`类型的对象包含单个字段,其类型为`char`。这个 [Character](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) 类还提供了许多用于操作字符的有用类(即静态)方法。
但是,有时候需要使用 char 作为对象 - 例如,作为期望对象的方法参数。 Java 编程语言提供了一个*包装器*类,为此目的“包装”`Character`对象中的`char``Character`类型的对象包含单个字段,其类型为`char`。这个 [Character](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) 类还提供了许多用于操作字符的有用类(即静态)方法。
您可以使用`Character`构造器创建`Character`对象:
......@@ -22,7 +22,7 @@ Character ch = new Character('a');
```
在某些情况下,Java 编译器还会为您创建一个`Character`对象。例如,如果将原始`char`传递给需要对象的方法,编译器会自动将`char`转换为`Character`。如果转换采用另一种方式,此功能称为 _ 自动装箱 _ - 或 _ 拆箱 _。有关自动装箱和拆箱的详细信息,请参阅[自动装箱和拆箱](autoboxing.html)
在某些情况下,Java 编译器还会为您创建一个`Character`对象。例如,如果将原始`char`传递给需要对象的方法,编译器会自动将`char`转换为`Character`。如果转换采用另一种方式,此功能称为*自动装箱 _ - 或*拆箱*。有关自动装箱和拆箱的详细信息,请参阅[自动装箱和拆箱](autoboxing.html)
* * *
......@@ -46,7 +46,7 @@ char toLowerCase(char ch)` | 返回指定 char 值的大写或小写形式
## 转义序列
前面带有反斜杠(\)的字符是 _ 转义序列 _,对编译器有特殊含义。下表显示了 Java 转义序列:
前面带有反斜杠(\)的字符是*转义序列*,对编译器有特殊含义。下表显示了 Java 转义序列:
Escape Sequences
| 逃脱序列 | 描述 |
......
......@@ -15,7 +15,7 @@ String greeting = "Hello world!";
```
在这种情况下,“Hello world!”是 _ 字符串文字 _ - 代码中的一系列字符,用双引号括起来。每当它在代码中遇到字符串文字时,编译器就会创建一个`String`对象及其值 - 在本例中为`Hello world!`
在这种情况下,“Hello world!”是*字符串文字 _ - 代码中的一系列字符,用双引号括起来。每当它在代码中遇到字符串文字时,编译器就会创建一个`String`对象及其值 - 在本例中为`Hello world!`
与任何其他对象一样,您可以使用`new`关键字和构造器创建`String`对象。 `String`类有 13 个构造器,允许您使用不同的源提供字符串的初始值,例如字符数组:
......@@ -36,7 +36,7 @@ System.out.println(helloString);
## 字符串长度
用于获取对象信息的方法称为 _ 存取方法 _。可以与字符串一起使用的一种访问器方法是`length()`方法,它返回字符串对象中包含的字符数。执行以下两行代码后,`len`等于 17:
用于获取对象信息的方法称为*存取方法*。可以与字符串一起使用的一种访问器方法是`length()`方法,它返回字符串对象中包含的字符数。执行以下两行代码后,`len`等于 17:
```java
String palindrome = "Dot saw I was Tod";
......@@ -44,7 +44,7 @@ int len = palindrome.length();
```
_ 回文 _ 是一个对称的单词或句子 - 它拼写相同的向前和向后,忽略大小写和标点符号。这是一个简短而低效的程序来反转回文串。它调用`String`方法`charAt(i)`,它返回字符串中的 i &lt;sup&gt;th&lt;/sup&gt; 字符,从 0 开始计数。
_ 回文*是一个对称的单词或句子 - 它拼写相同的向前和向后,忽略大小写和标点符号。这是一个简短而低效的程序来反转回文串。它调用`String`方法`charAt(i)`,它返回字符串中的 i &lt;sup&gt;th&lt;/sup&gt; 字符,从 0 开始计数。
```java
public class StringDemo {
......
......@@ -81,7 +81,7 @@ int lastIndexOf(String str,int fromIndex)` | 返回指定子字符串的
`String`类只有很少的方法可以将字符或子串插入到字符串中。通常,它们不是必需的:您可以通过连接从中删除的子字符串来创建一个新字符串,该字符串包含您要插入的子字符串。
然而,`String`类确实有四种 _ 替换 _ 找到的字符或子串的方法。他们是:
然而,`String`类确实有四种*替换*找到的字符或子串的方法。他们是:
Methods in the `String` Class for Manipulating Strings
| 方法 | 描述 |
......
......@@ -6,7 +6,7 @@
**问题 1** :编译用 Java 编程语言编写的程序时,编译器会将人类可读的源文件转换为 Java 虚拟机可以理解的与平台无关的代码。这个与平台无关的代码叫什么?
**问题 2** :以下哪一项是 _ 而不是 _ 的有效评论:
**问题 2** :以下哪一项是*而不是*的有效评论:
一个。 `/** comment */`
b。 `/* comment */`
......
......@@ -10,7 +10,7 @@
`String`类一样,`StringBuilder`类具有`length()`方法,该方法返回构建器中字符序列的长度。
与字符串不同,每个字符串构建器还具有 _ 容量 _,即已分配的字符空间数。由`capacity()`方法返回的容量始终大于或等于长度(通常大于),并将根据需要自动扩展以适应字符串构建器的添加。
与字符串不同,每个字符串构建器还具有*容量*,即已分配的字符空间数。由`capacity()`方法返回的容量始终大于或等于长度(通常大于),并将根据需要自动扩展以适应字符串构建器的添加。
`StringBuilder` Constructors
| 构造器 | 描述 |
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/data/stringsummary.html](https://docs.oracle.com/javase/tutorial/java/data/stringsummary.html)
大多数情况下,如果使用单个字符值,则将使用原始`char`类型。但是,有时候需要使用 char 作为对象 - 例如,作为期望对象的方法参数。 Java 编程语言提供了一个 _ 包装器 _ 类,为此目的“包装”`Character`对象中的`char``Character`类型的对象包含单个字段,其类型为`char`。该 [`Character`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) 类还提供了许多用于操纵字符的有用类(即静态)方法。
大多数情况下,如果使用单个字符值,则将使用原始`char`类型。但是,有时候需要使用 char 作为对象 - 例如,作为期望对象的方法参数。 Java 编程语言提供了一个*包装器*类,为此目的“包装”`Character`对象中的`char``Character`类型的对象包含单个字段,其类型为`char`。该 [`Character`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) 类还提供了许多用于操纵字符的有用类(即静态)方法。
字符串是一系列字符,广泛用于 Java 编程。在 Java 编程语言中,字符串是对象。 [`String`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) 类有 60 多种方法和 13 种构造器。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
_Autoboxing_ 是 Java 编译器在原始类型和相应的对象包装类之间进行的自动转换。例如,将`int`转换为`整数``双`转换为`Double` ,依此类推。如果转换是另一种方式,则称为 _ 拆箱 _
_Autoboxing_ 是 Java 编译器在原始类型和相应的对象包装类之间进行的自动转换。例如,将`int`转换为`整数``双`转换为`Double` ,依此类推。如果转换是另一种方式,则称为*拆箱*
以下是自动装箱的最简单示例:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/why.html](https://docs.oracle.com/javase/tutorial/java/generics/why.html)
简而言之,泛型使 _ 类型 _(类和接口)在定义类,接口和方法时成为参数。与方法声明中使用的更熟悉的 _ 形式参数 _ 非常相似,类型参数提供了一种方法,您可以使用不同的输入重用相同的代码。不同之处在于形式参数的输入是值,而类型参数的输入是类型。
简而言之,泛型使*类型*(类和接口)在定义类,接口和方法时成为参数。与方法声明中使用的更熟悉的*形式参数*非常相似,类型参数提供了一种方法,您可以使用不同的输入重用相同的代码。不同之处在于形式参数的输入是值,而类型参数的输入是类型。
使用泛型的代码比非泛型代码有许多好处:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/types.html](https://docs.oracle.com/javase/tutorial/java/generics/types.html)
_ 泛型类型 _ 是通过类型参数化的泛型类或接口。以下`Box`类将被修改以演示该概念。
_ 泛型类型*是通过类型参数化的泛型类或接口。以下`Box`类将被修改以演示该概念。
## 一个简单的盒子类
......@@ -22,16 +22,16 @@ public class Box {
## Box 类的通用版本
_ 泛型类 _ 使用以下格式定义:
_ 泛型类*使用以下格式定义:
```java
class name<T1, T2, ..., Tn> { /* ... */ }
```
由尖括号(`<>` )分隔的类型参数部分遵循类名。它指定 _ 类型参数 _(也称为 _ 类型变量 _`T1``T2` ,......和`Tn` ]。
由尖括号(`<>` )分隔的类型参数部分遵循类名。它指定*类型参数*(也称为*类型变量*`T1``T2` ,......和`Tn` ]。
要更新`Box`类以使用泛型,您可以通过将代码“ `public class Box` ”更改为“ `public class Box&lt”来创建 _ 泛型类型声明 _ ; T>` “。这引入了类型变量`T` ,可以在类中的任何地方使用。
要更新`Box`类以使用泛型,您可以通过将代码“ `public class Box` ”更改为“ `public class Box&lt”来创建*泛型类型声明 _ ; T>` “。这引入了类型变量`T` ,可以在类中的任何地方使用。
通过此更改, `Box`类变为:
......@@ -69,14 +69,14 @@ public class Box<T> {
您将在整个 Java SE API 和本课程的其余部分中看到这些名称。
要从代码中引用通用`Box`类,必须执行 _ 泛型类型调用 _,它将`T`替换为某些具体值,例如`整数`
要从代码中引用通用`Box`类,必须执行*泛型类型调用*,它将`T`替换为某些具体值,例如`整数`
```java
Box<Integer> integerBox;
```
您可以将泛型类型调用视为与普通方法调用类似,但不是将参数传递给方法,而是在这种情况下传递 _ 类型参数 _ - `Integer` - 到`Box`类本身。
您可以将泛型类型调用视为与普通方法调用类似,但不是将参数传递给方法,而是在这种情况下传递*类型参数 _ - `Integer` - 到`Box`类本身。
* * *
......@@ -86,7 +86,7 @@ Box<Integer> integerBox;
与任何其他变量声明一样,此代码实际上不会创建新的`Box`对象。它简单地声明`integerBox`将保持对`Integer`的“ `Box` ”的引用,这是`Box&lt; Integer>`被阅读。
泛型类型的调用通常称为 _ 参数化类型 _
泛型类型的调用通常称为*参数化类型*
要实例化此类,像往常一样使用`new`关键字,但放置`< Integer&gt;类名和括号之间的`
......@@ -95,7 +95,7 @@ Box<Integer> integerBox = new Box<Integer>();
```
在 Java SE 7 及更高版本中,只要编译器可以确定或推断类型参数,就可以用一组空的类型参数(&lt;&gt;)替换调用泛型类的构造器所需的类型参数。上下文。这对尖括号&lt;&gt;非正式地称为 _ 钻石 _。例如,您可以创建`Box&lt; Integer&gt;的实例。` ,声明如下:
在 Java SE 7 及更高版本中,只要编译器可以确定或推断类型参数,就可以用一组空的类型参数(&lt;&gt;)替换调用泛型类的构造器所需的类型参数。上下文。这对尖括号&lt;&gt;非正式地称为*钻石*。例如,您可以创建`Box&lt; Integer&gt;的实例。` ,声明如下:
```java
Box<Integer> integerBox = new Box<>();
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html](https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html)
_ 原始类型 _ 是没有任何类型参数的泛型类或接口的名称。例如,给定通用`Box`类:
_ 原始类型*是没有任何类型参数的泛型类或接口的名称。例如,给定通用`Box`类:
```java
public class Box<T> {
......@@ -26,7 +26,7 @@ Box rawBox = new Box();
```
因此, `Box`是泛型类型`Box&lt; T&gt;的原始类型。` 。但是,非泛型类或接口类型是 _ 而不是 _ 原始类型。
因此, `Box`是泛型类型`Box&lt; T&gt;的原始类型。` 。但是,非泛型类或接口类型是*而不是*原始类型。
原始类型显示在遗留代码中,因为许多 API 类(例如`集合`类)在 JDK 5.0 之前不是通用的。当使用原始类型时,你基本上得到了前仿制行为 - `Box`给你`对象`。为了向后兼容,允许将参数化类型分配给其原始类型:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/methods.html](https://docs.oracle.com/javase/tutorial/java/generics/methods.html)
_ 通用方法 _ 是引入自己的类型参数的方法。这类似于声明泛型类型,但类型参数的范围仅限于声明它的方法。允许使用静态和非静态泛型方法,以及泛型类构造器。
_ 通用方法*是引入自己的类型参数的方法。这类似于声明泛型类型,但类型参数的范围仅限于声明它的方法。允许使用静态和非静态泛型方法,以及泛型类构造器。
泛型方法的语法包括一个类型参数列表,在尖括号内,它出现在方法的返回类型之前。对于静态泛型方法,类型参数部分必须出现在方法的返回类型之前。
......@@ -52,4 +52,4 @@ boolean same = Util.compare(p1, p2);
```
此功能称为 _ 类型推断 _,允许您将普通方法作为普通方法调用,而无需在尖括号之间指定类型。本主题将在下一节[类型推断](genTypeInference.html)中进一步讨论。
\ No newline at end of file
此功能称为*类型推断*,允许您将普通方法作为普通方法调用,而无需在尖括号之间指定类型。本主题将在下一节[类型推断](genTypeInference.html)中进一步讨论。
\ No newline at end of file
......@@ -42,7 +42,7 @@ C:\jdk1.8.0\bin\javac HelloWorldApp.java
**语法错误(所有平台)**
如果您错误地键入了程序的一部分,编译器可能会发出 _ 语法 _ 错误。该消息通常显示错误的类型,检测到错误的行号,该行上的代码以及代码中错误的位置。这是在语句末尾省略分号(`;`)导致的错误:
如果您错误地键入了程序的一部分,编译器可能会发出*语法*错误。该消息通常显示错误的类型,检测到错误的行号,该行上的代码以及代码中错误的位置。这是在语句末尾省略分号(`;`)导致的错误:
```java
testing.java:14: `;' expected.
......@@ -121,7 +121,7 @@ set CLASSPATH=
`**无法找到或加载主类 HelloWorldApp.class**`
初学者程序员常犯的一个错误就是尝试在编译器创建的`.class`文件上运行`java`启动程序。例如,如果您尝试使用`java HelloWorldApp.class`而不是`java HelloWorldApp`运行程序,则会出现此错误。请记住,参数是您要使用的类的 _ 名称,_ 而不是 _ 文件名。_
初学者程序员常犯的一个错误就是尝试在编译器创建的`.class`文件上运行`java`启动程序。例如,如果您尝试使用`java HelloWorldApp.class`而不是`java HelloWorldApp`运行程序,则会出现此错误。请记住,参数是您要使用的类的*名称,*而不是*文件名。_
**`Exception in thread "main" java.lang.NoSuchMethodError: main`**
......@@ -153,7 +153,7 @@ unset CLASSPATH
`**线程“main”中的异常 java.lang.NoClassDefFoundError:HelloWorldApp / class**`
初学者程序员常犯的一个错误就是尝试在编译器创建的`.class`文件上运行`java`启动程序。例如,如果您尝试使用`java HelloWorldApp.class`而不是`java HelloWorldApp`运行程序,则会出现此错误。请记住,参数是您要使用的类的 _ 名称,_ 而不是 _ 文件名。_
初学者程序员常犯的一个错误就是尝试在编译器创建的`.class`文件上运行`java`启动程序。例如,如果您尝试使用`java HelloWorldApp.class`而不是`java HelloWorldApp`运行程序,则会出现此错误。请记住,参数是您要使用的类的*名称,*而不是*文件名。_
**`Exception in thread "main" java.lang.NoSuchMethodError: main`**
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/bounded.html](https://docs.oracle.com/javase/tutorial/java/generics/bounded.html)
有时您可能希望限制可在参数化类型中用作类型参数的类型。例如,对数字进行操作的方法可能只想接受`Number`或其子类的实例。这是 _ 有界类型参数 _ 的用途。
有时您可能希望限制可在参数化类型中用作类型参数的类型。例如,对数字进行操作的方法可能只想接受`Number`或其子类的实例。这是*有界类型参数*的用途。
要声明有界类型参数,请列出类型参数的名称,后跟`extends`关键字,然后是 _ 上限 _,在此示例中为`Number`。请注意,在此上下文中,`extends`在一般意义上用于表示“扩展”(如在类中)或“实现”(如在接口中)。
要声明有界类型参数,请列出类型参数的名称,后跟`extends`关键字,然后是*上限*,在此示例中为`Number`。请注意,在此上下文中,`extends`在一般意义上用于表示“扩展”(如在类中)或“实现”(如在接口中)。
```java
public class Box<T> {
......@@ -66,7 +66,7 @@ public class NaturalNumber<T extends Integer> {
## 多个边界
前面的示例说明了使用带有单个边界的类型参数,但是类型参数可以具有 _ 多个边界 _
前面的示例说明了使用带有单个边界的类型参数,但是类型参数可以具有*多个边界*
```java
<T extends B1 & B2 & B3>
......
......@@ -11,7 +11,7 @@ someObject = someInteger; // OK
```
在面向对象的术语中,这被称为“是一种”关系。由于`整数` _ 是 _ `对象`,因此允许分配。但是`Integer`也是一种`Number` ,所以下面的代码也是有效的:
在面向对象的术语中,这被称为“是一种”关系。由于`整数` _ 是*`对象`,因此允许分配。但是`Integer`也是一种`Number` ,所以下面的代码也是有效的:
```java
public void someMethod(Number n) { /* ... */ }
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html](https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)
_ 类型推断 _ 是 Java 编译器查看每个方法调用和相应声明以确定使调用适用的类型参数(或参数)的能力。推理算法确定参数的类型,如果可用,还确定分配或返回结果的类型。最后,推理算法试图找到适用于所有参数的 _ 最具体 _ 类型。
_ 类型推断*是 Java 编译器查看每个方法调用和相应声明以确定使调用适用的类型参数(或参数)的能力。推理算法确定参数的类型,如果可用,还确定分配或返回结果的类型。最后,推理算法试图找到适用于所有参数的*最具体*类型。
为了说明最后一点,在下面的例子中,推断确定传递给`pick`方法的第二个参数是`Serializable`类型:
......@@ -55,7 +55,7 @@ Box #2 contains [30]
```
泛型方法`addBox`定义了一个名为`U`的类型参数。通常,Java 编译器可以推断泛型方法调用的类型参数。因此,在大多数情况下,您不必指定它们。例如,要调用泛型方法`addBox`,可以使用 _ 类型见证 _ 指定类型参数,如下所示:
泛型方法`addBox`定义了一个名为`U`的类型参数。通常,Java 编译器可以推断泛型方法调用的类型参数。因此,在大多数情况下,您不必指定它们。例如,要调用泛型方法`addBox`,可以使用*类型见证*指定类型参数,如下所示:
```java
BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
......@@ -127,7 +127,7 @@ MyClass<Integer> myObject = new MyClass<>("");
* * *
Java 编译器利用目标类型来推断泛型方法调用的类型参数。表达式的 _ 目标类型 _ 是 Java 编译器所期望的数据类型,具体取决于表达式的显示位置。考虑方法`Collections.emptyList`,声明如下:
Java 编译器利用目标类型来推断泛型方法调用的类型参数。表达式的*目标类型*是 Java 编译器所期望的数据类型,具体取决于表达式的显示位置。考虑方法`Collections.emptyList`,声明如下:
```java
static <T> List<T> emptyList();
......
......@@ -2,6 +2,6 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html](https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html)
在通用代码中,问号(`?`),称为 _ 通配符 _,表示未知类型。通配符可用于各种情况:作为参数,字段或局部变量的类型;有时作为返回类型(虽然更好的编程实践更具体)。通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数。
在通用代码中,问号(`?`),称为*通配符*,表示未知类型。通配符可用于各种情况:作为参数,字段或局部变量的类型;有时作为返回类型(虽然更好的编程实践更具体)。通配符从不用作泛型方法调用,泛型类实例创建或超类型的类型参数。
以下部分更详细地讨论通配符,包括上限有界通配符,下限有界通配符和通配符捕获。
\ No newline at end of file
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html](https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html)
您可以使用上限通配符来放宽对变量的限制。例如,假设您要编写一个适用于`List&lt; Integer&gt;的方法。``列表&lt; Double>`_ 和 _ `列表&lt; Number>` ;你可以通过使用上限的通配符来实现这一点。
您可以使用上限通配符来放宽对变量的限制。例如,假设您要编写一个适用于`List&lt; Integer&gt;的方法。``列表&lt; Double>`*和 _ `列表&lt; Number>` ;你可以通过使用上限的通配符来实现这一点。
要声明一个上限通配符,使用通配符('`?`'),然后是`extends`关键字,然后是 _ 上限 _。注意,在这种情况下,`扩展`在一般意义上用于表示“扩展”(如在类中)或“实现”(如在接口中)。
要声明一个上限通配符,使用通配符('`?`'),然后是`extends`关键字,然后是*上限*。注意,在这种情况下,`扩展`在一般意义上用于表示“扩展”(如在类中)或“实现”(如在接口中)。
编写适用于`编号`列表和`编号`的子类型的方法,如`整数``Double``浮动`,你要指定`List&lt;? extends Number>` 。术语`列表&lt;数字>``List&lt;?更具限制性 extends Number>`因为前者仅匹配类型`号`的列表,而后者匹配类型`号`或其任何子类的列表。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html](https://docs.oracle.com/javase/tutorial/java/generics/unboundedWildcards.html)
使用通配符(`?`)指定无界通配符类型,例如, `List&lt;?>` 。这被称为未知类型的 _ 列表 _。有两种情况,无界通配符是一种有用的方法:
使用通配符(`?`)指定无界通配符类型,例如, `List&lt;?>` 。这被称为未知类型的*列表*。有两种情况,无界通配符是一种有用的方法:
* 如果您正在编写可以使用`Object`类中提供的功能实现的方法。
* 当代码使用泛型类中不依赖于类型参数的方法时。例如, `List.size``List.clear` 。事实上, `Class&lt;?>`经常被使用,因为`Class&lt; T&gt;中的大部分方法都是如此。`不依赖于`T`
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html](https://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html)
[上限有界通配符](upperBounded.html)部分显示上限有界通配符将未知类型限制为该类型的特定类型或子类型,并使用`extends`关键字表示。以类似的方式,_ 下限 _ 通配符将未知类型限制为该类型的特定类型或 _ 超类型 _
[上限有界通配符](upperBounded.html)部分显示上限有界通配符将未知类型限制为该类型的特定类型或子类型,并使用`extends`关键字表示。以类似的方式,*下限*通配符将未知类型限制为该类型的特定类型或*超类型*
使用通配符('`?`')表示下限通配符,后跟`super`关键字,然后是 _ 下限 _`&lt ;?超级 A>`
使用通配符('`?`')表示下限通配符,后跟`super`关键字,然后是*下限*`&lt ;?超级 A>`
* * *
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/generics/capture.html](https://docs.oracle.com/javase/tutorial/java/generics/capture.html)
在某些情况下,编译器会推断出通配符的类型。例如,列表可以被定义为`List&lt;?&gt;。`但是,在评估表达式时,编译器会从代码中推断出特定的类型。这种情况称为 _ 通配符捕获 _
在某些情况下,编译器会推断出通配符的类型。例如,列表可以被定义为`List&lt;?&gt;。`但是,在评估表达式时,编译器会从代码中推断出特定的类型。这种情况称为*通配符捕获*
在大多数情况下,您不必担心通配符捕获,除非您看到包含短语“capture of”的错误消息。
......@@ -39,7 +39,7 @@ WildcardError.java:6: error: method set in interface List<E> cannot be applied t
```
在此示例中,代码尝试执行安全操作,那么如何解决编译器错误?您可以通过编写捕获通配符的 _ 私有帮助程序方法 _ 来修复它。在这种情况下,您可以通过创建私有帮助方法`fooHelper`来解决问题,如 [`WildcardFixed`](examples/WildcardFixed.java) 所示:
在此示例中,代码尝试执行安全操作,那么如何解决编译器错误?您可以通过编写捕获通配符的*私有帮助程序方法*来修复它。在这种情况下,您可以通过创建私有帮助方法`fooHelper`来解决问题,如 [`WildcardFixed`](examples/WildcardFixed.java) 所示:
```java
public class WildcardFixed {
......
......@@ -12,7 +12,7 @@
[![trail icon](img/6701b9a7baaf24d8cc41f70c529f43f8.jpg) **注释**](annotations/index.html) 是元数据的一种形式,为编译器提供信息。本课程描述了在程序中有效使用注释的位置和方法。
[![trail icon](img/6701b9a7baaf24d8cc41f70c529f43f8.jpg) **接口和继承**](IandI/index.html) 描述了接口 - 它们是什么,为什么要写一个,以及如何写一个。本节还介绍了从另一个类派生一个类的方法。也就是说,_ 子类 _ 如何从 _ 超类 _ 继承字段和方法。您将了解到所有类都派生自`Object`类,以及如何修改子类从超类继承的方法。
[![trail icon](img/6701b9a7baaf24d8cc41f70c529f43f8.jpg) **接口和继承**](IandI/index.html) 描述了接口 - 它们是什么,为什么要写一个,以及如何写一个。本节还介绍了从另一个类派生一个类的方法。也就是说,*子类*如何从*超类*继承字段和方法。您将了解到所有类都派生自`Object`类,以及如何修改子类从超类继承的方法。
[![trail icon](img/6701b9a7baaf24d8cc41f70c529f43f8.jpg) **数字和字符串**](data/index.html) 本课程介绍如何使用`Number``String`对象本课程还介绍如何格式化输出数据。
......
......@@ -57,7 +57,7 @@ Integer x = (String)mn.data; // Causes a ClassCastException to be thrown.
* 通过`mn`引用的同一对象的数据字段可以被访问并且预期是整数(因为`mn``MyNode` ,它是`节点&lt;整数>`
* 尝试将`字符串`分配给`整数`会导致`ClassCastException`来自 Java 编译器在赋值时插入的强制转换。
在编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建一个称为 _ 桥接方法 _ 的合成​​方法,作为类型擦除过程的一部分。您通常不需要担心桥接方法,但如果出现在堆栈跟踪中,您可能会感到困惑。
在编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建一个称为*桥接方法*的合成​​方法,作为类型擦除过程的一部分。您通常不需要担心桥接方法,但如果出现在堆栈跟踪中,您可能会感到困惑。
在类型擦除之后,`节点``MyNode`类变为:
......
......@@ -11,11 +11,11 @@
* [具有不可恢复形式参数的 Varargs 方法的潜在漏洞](#vulnerabilities)
* [使用不可恢复的形式参数防止 Varargs 方法出现警告](#suppressing)
_ 可再生 _ 类型是一种类型信息在运行时完全可用的类型。这包括基元,非泛型类型,原始类型和未绑定通配符的调用。
_ 可再生*类型是一种类型信息在运行时完全可用的类型。这包括基元,非泛型类型,原始类型和未绑定通配符的调用。
_ 不可再生类型 _ 是在编译时通过类型擦除删除信息的类型 - 未定义为无界通配符的泛型类型的调用。不可重新生成的类型在运行时没有提供所有信息。不可再生类型的示例是`List&lt; String&gt;。``列表&lt; Number>` ; JVM 无法在运行时区分这些类型。如[对泛型的限制](restrictions.html)所示,在某些情况下不能使用不可再生类型:例如,在`表达式`表达式中,或作为数组中的元素。
_ 不可再生类型*是在编译时通过类型擦除删除信息的类型 - 未定义为无界通配符的泛型类型的调用。不可重新生成的类型在运行时没有提供所有信息。不可再生类型的示例是`List&lt; String&gt;。``列表&lt; Number>` ; JVM 无法在运行时区分这些类型。如[对泛型的限制](restrictions.html)所示,在某些情况下不能使用不可再生类型:例如,在`表达式`表达式中,或作为数组中的元素。
_ 当参数化类型的变量引用不是该参数化类型的对象时,会发生堆污染 _。如果程序执行某些操作,在编译时产生未经检查的警告,则会出现这种情况。如果在编译时(在编译时类型检查规则的限制范围内)或在运行时,生成 _ 未检查警告 _,则涉及参数化类型的操作的正确性(例如,强制转换)或方法调用)无法验证。例如,在混合原始类型和参数化类型时,或者在执行未经检查的强制转换时,会发生堆污染。
_ 当参数化类型的变量引用不是该参数化类型的对象时,会发生堆污染*。如果程序执行某些操作,在编译时产生未经检查的警告,则会出现这种情况。如果在编译时(在编译时类型检查规则的限制范围内)或在运行时,生成*未检查警告*,则涉及参数化类型的操作的正确性(例如,强制转换)或方法调用)无法验证。例如,在混合原始类型和参数化类型时,或者在执行未经检查的强制转换时,会发生堆污染。
在正常情况下,当所有代码同时编译时,编译器会发出未经检查的警告,以引起您对潜在堆污染的注意。如果单独编译代码的各个部分,则很难检测到堆污染的潜在风险。如果确保代码在没有警告的情况下编译,则不会发生堆污染。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/package/createpkgs.html](https://docs.oracle.com/javase/tutorial/java/package/createpkgs.html)
要创建包,请选择包的名称(命名约定将在下一节中讨论),并在 _ 顶部放置一个带有该名称的`package`语句,每个包含类型的源文件 _(要包含在包中的类,接口,枚举和注释类型。
要创建包,请选择包的名称(命名约定将在下一节中讨论),并在*顶部放置一个带有该名称的`package`语句,每个包含类型的源文件*(要包含在包中的类,接口,枚举和注释类型。
package 语句(例如,`package graphics;`)必须是源文件中的第一行。每个源文件中只能有一个 package 语句,它适用于文件中的所有类型。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/package/usepkgs.html](https://docs.oracle.com/javase/tutorial/java/package/usepkgs.html)
组成包的类型称为 _ 包成员 _
组成包的类型称为*包成员*
要从包外部使用`public`包成员,您必须执行以下操作之一:
......@@ -30,7 +30,7 @@ graphics.Rectangle myRect = new graphics.Rectangle();
```
合格的名称可以不经常使用。但是,当重复使用名称时,重复键入名称会变得乏味,并且代码变得难以阅读。作为替代方案,您可以 _ 导入 _ 成员或其包,然后使用其简单名称。
合格的名称可以不经常使用。但是,当重复使用名称时,重复键入名称会变得乏味,并且代码变得难以阅读。作为替代方案,您可以*导入*成员或其包,然后使用其简单名称。
## 导入包成员
......@@ -97,9 +97,9 @@ Another less common form of `import`, the _static import statement_, will be dis
## 包的表观层次结构
首先,包似乎是分层的,但它们不是。例如,Java API 包括`java.awt`包,`java.awt.color`包,`java.awt.font`包以及以`java.awt`开头的许多其他包。但是,`java.awt.color`封装,`java.awt.font`封装和其他`java.awt.xxxx`封装 _ 不包含在`java.awt`封装中的 _ 中。前缀`java.awt`(Java 抽象窗口工具包)用于许多相关的包,以使关系明显,但不显示包含。
首先,包似乎是分层的,但它们不是。例如,Java API 包括`java.awt`包,`java.awt.color`包,`java.awt.font`包以及以`java.awt`开头的许多其他包。但是,`java.awt.color`封装,`java.awt.font`封装和其他`java.awt.xxxx`封装*不包含在`java.awt`封装中的*中。前缀`java.awt`(Java 抽象窗口工具包)用于许多相关的包,以使关系明显,但不显示包含。
导入`java.awt.*`会导入`java.awt`包中的所有类型,但 _ 不会导入 _ `java.awt.color``java.awt.font`或任何其他`java.awt.xxxx`包。如果您计划使用`java.awt.color`中的类和其他类型以及`java.awt`中的类,则必须导入包含所有文件的包:
导入`java.awt.*`会导入`java.awt`包中的所有类型,但*不会导入 _ `java.awt.color``java.awt.font`或任何其他`java.awt.xxxx`包。如果您计划使用`java.awt.color`中的类和其他类型以及`java.awt`中的类,则必须导入包含所有文件的包:
```java
import java.awt.*;
......@@ -123,7 +123,7 @@ graphics.Rectangle rect;
```
在某些情况下,您需要经常访问静态最终字段(常量)和来自一个或两个类的静态方法。反复对这些类的名称进行前缀可能会导致代码混乱。 _ 静态导入 _ 语句为您提供了一种导入要使用的常量和静态方法的方法,这样您就不需要为其类的名称添加前缀。
在某些情况下,您需要经常访问静态最终字段(常量)和来自一个或两个类的静态方法。反复对这些类的名称进行前缀可能会导致代码混乱。*静态导入*语句为您提供了一种导入要使用的常量和静态方法的方法,这样您就不需要为其类的名称添加前缀。
`java.lang.Math`类定义`PI`常量和许多静态方法,包括计算正弦,余弦,切线,平方根,最大值,最小值,指数等的方法。例如,
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/package/managingfiles.html](https://docs.oracle.com/javase/tutorial/java/package/managingfiles.html)
Java 平台的许多实现依赖于分层文件系统来管理源文件和类文件,尽管 _Java 语言规范 _ 不要求这样做。策略如下。
Java 平台的许多实现依赖于分层文件系统来管理源文件和类文件,尽管 _Java 语言规范*不要求这样做。策略如下。
将类,接口,枚举或注释类型的源代码放在文本文件中,该文件的名称是类型的简单名称,其扩展名为`.java`。例如:
......@@ -68,7 +68,7 @@ class Helper{
通过这样做,您可以将`classes`目录提供给其他程序员而不会泄露您的来源。您还需要以这种方式管理源文件和类文件,以便编译器和 Java 虚拟机(JVM)可以找到程序使用的所有类型。
`classes`目录的完整路径`<path_two&gt;\classes`称为 _ 类路径 _,并使用`CLASSPATH`系统变量设置。编译器和 JVM 都通过将包名添加到类路径来构造`.class`文件的路径。例如,如果
`classes`目录的完整路径`<path_two&gt;\classes`称为*类路径*,并使用`CLASSPATH`系统变量设置。编译器和 JVM 都通过将包名添加到类路径来构造`.class`文件的路径。例如,如果
```java
<path_two>\classes
......
......@@ -26,6 +26,6 @@ Destination Packages
* [`Utilities`](question/Utilities.java)
1. 使用刚刚下载的源文件实现您在问题 1 到 3 中提出的更改。
2. 编译修改后的源文件。 (_ 提示:_ 如果从命令行调用编译器(而不是使用构建器),请从包含刚刚创建的`mygame`目录的目录中调用编译器。)
2. 编译修改后的源文件。 (*提示:*如果从命令行调用编译器(而不是使用构建器),请从包含刚刚创建的`mygame`目录的目录中调用编译器。)
[Check your answers.](packages-answers.html)
\ No newline at end of file
......@@ -6,7 +6,7 @@
[![Trail icon](img/0689397fa9cc4e369d63fc92b3bb6f38.jpg) **例外**](exceptions/index.html) 解释了异常机制以及它如何用于处理错误和其他异常情况。本课程描述了异常是什么,如何抛出和捕获异常,一旦捕获异常后如何处理异常,以及如何使用异常类层次结构。
[![Trail icon](img/0689397fa9cc4e369d63fc92b3bb6f38.jpg) **基本 I / O **](io/index.html) 涵盖用于基本输入和输出的 Java 平台类。它主要关注 _I / O 流 _,这是一个强大的概念,可以大大简化 I / O 操作。本课程还介绍了序列化,它允许程序将整个对象写入流并再次读回。然后,本课程将介绍一些文件系统操作,包括随机访问文件。最后,它简要介绍了新 I / O API 的高级功能。
[![Trail icon](img/0689397fa9cc4e369d63fc92b3bb6f38.jpg) **基本 I / O **](io/index.html) 涵盖用于基本输入和输出的 Java 平台类。它主要关注 _I / O 流*,这是一个强大的概念,可以大大简化 I / O 操作。本课程还介绍了序列化,它允许程序将整个对象写入流并再次读回。然后,本课程将介绍一些文件系统操作,包括随机访问文件。最后,它简要介绍了新 I / O API 的高级功能。
[![Trail icon](img/0689397fa9cc4e369d63fc92b3bb6f38.jpg) **并发**](concurrency/index.html) 解释了如何编写同时执行多个任务的应用程序。 Java 平台的设计初衷是为了支持并发编程,在 Java 编程语言和 Java 类库中提供基本的并发支持。从 5.0 版开始,Java 平台还包含高级并发 API。本课程介绍了平台的基本并发支持,并总结了`java.util.concurrent`包中的一些高级 API。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
Java 编程语言使用 _ 异常 _ 来处理错误和其他异常事件。本课程介绍何时以及如何使用异常。
Java 编程语言使用*异常*来处理错误和其他异常事件。本课程介绍何时以及如何使用异常。
## [什么是例外?](definition.html)
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html)
术语 _ 异常 _ 是短语“异常事件”的简写。
术语*异常*是短语“异常事件”的简写。
* * *
......@@ -10,9 +10,9 @@
* * *
当方法中发生错误时,该方法会创建一个对象并将其交给运行时系统。该对象称为 _ 异常对象 _,包含有关错误的信息,包括错误发生时的类型和程序状态。创建异常对象并将其交给运行时系统称为 _ 抛出异常 _
当方法中发生错误时,该方法会创建一个对象并将其交给运行时系统。该对象称为*异常对象*,包含有关错误的信息,包括错误发生时的类型和程序状态。创建异常对象并将其交给运行时系统称为*抛出异常*
在方法抛出异常后,运行时系统会尝试查找要处理它的内容。处理异常的可能“某事”的集合是已被调用以获取发生错误的方法的有序方法列表。方法列表称为 _ 调用堆栈 _(参见下一个图)。
在方法抛出异常后,运行时系统会尝试查找要处理它的内容。处理异常的可能“某事”的集合是已被调用以获取发生错误的方法的有序方法列表。方法列表称为*调用堆栈*(参见下一个图)。
![The call stack showing three method calls, where the first method called has the exception handler.](img/a3ada6aaec8cd7196e8ac704d5f246c3.jpg)
......@@ -20,9 +20,9 @@
运行时系统在调用堆栈中搜索包含可处理异常的代码块的方法。这段代码称为 _ 异常处理器 _。搜索从发生错误的方法开始,并按照调用方法的相反顺序继续通过调用堆栈。找到适当的处理器后,运行时系统会将异常传递给处理器。如果抛出的异常对象的类型与处理器可以处理的类型匹配,则认为异常处理器是合适的。
运行时系统在调用堆栈中搜索包含可处理异常的代码块的方法。这段代码称为*异常处理器*。搜索从发生错误的方法开始,并按照调用方法的相反顺序继续通过调用堆栈。找到适当的处理器后,运行时系统会将异常传递给处理器。如果抛出的异常对象的类型与处理器可以处理的类型匹配,则认为异常处理器是合适的。
选择的异常处理器称 _ 捕获异常 _。如果运行时系统穷举搜索调用堆栈上的所有方法而没有找到适当的异常处理器,如下图所示,则运行时系统(以及程序)终止。
选择的异常处理器称*捕获异常*。如果运行时系统穷举搜索调用堆栈上的所有方法而没有找到适当的异常处理器,如下图所示,则运行时系统(以及程序)终止。
![The call stack showing three method calls, where the first method called has the exception handler.](img/0d275d710fa7beac49efa736d9ad13f5.jpg)
......
......@@ -13,19 +13,19 @@
## 三种例外
第一种例外是 _ 检查异常 _。这些是编写良好的应用程序应该预期和恢复的特殊条件。例如,假设应用程序提示用户输入文件名,然后通过将名称传递给`java.io.FileReader`的构造器来打开文件。通常,用户提供现有可读文件的名称,因此`FileReader`对象的构造成功,并且应用程序的执行正常进行。但有时用户提供不存在的文件的名称,构造器抛出`java.io.FileNotFoundException`。一个编写良好的程序将捕获此异常并通知用户该错误,可能提示更正的文件名。
第一种例外是*检查异常*。这些是编写良好的应用程序应该预期和恢复的特殊条件。例如,假设应用程序提示用户输入文件名,然后通过将名称传递给`java.io.FileReader`的构造器来打开文件。通常,用户提供现有可读文件的名称,因此`FileReader`对象的构造成功,并且应用程序的执行正常进行。但有时用户提供不存在的文件的名称,构造器抛出`java.io.FileNotFoundException`。一个编写良好的程序将捕获此异常并通知用户该错误,可能提示更正的文件名。
已检查的异常 _ 将 _ 置于“捕获”或“指定要求”中。除`Error``RuntimeException`及其子类指示的异常外,所有异常都是经过检查的异常。
已检查的异常*将*置于“捕获”或“指定要求”中。除`Error``RuntimeException`及其子类指示的异常外,所有异常都是经过检查的异常。
第二种例外是 _ 错误 _。这些是应用程序外部的特殊条件,应用程序通常无法预测或恢复。例如,假设应用程序成功打开文件以进行输入,但由于硬件或系统故障而无法读取文件。不成功的读取将抛出`java.io.IOError`。应用程序可能会选择捕获此异常,以便通知用户该问题 - 但它也可能有助于程序打印堆栈跟踪并退出。
第二种例外是*错误*。这些是应用程序外部的特殊条件,应用程序通常无法预测或恢复。例如,假设应用程序成功打开文件以进行输入,但由于硬件或系统故障而无法读取文件。不成功的读取将抛出`java.io.IOError`。应用程序可能会选择捕获此异常,以便通知用户该问题 - 但它也可能有助于程序打印堆栈跟踪并退出。
错误 _ 不受[捕获或指定要求]_ 的影响。错误是`Error`及其子类指示的异常。
错误*不受[捕获或指定要求]_ 的影响。错误是`Error`及其子类指示的异常。
第三种例外是 _ 运行时异常 _。这些是应用程序内部的异常条件,应用程序通常无法预测或恢复。这些通常表示编程错误,例如逻辑错误或 API 的不当使用。例如,考虑前面描述的应用程序将文件名传递给`FileReader`的构造器。如果逻辑错误导致`null`传递给构造器,构造器将抛出`NullPointerException`。应用程序可以捕获此异常,但消除导致异常发生的错误可能更有意义。
第三种例外是*运行时异常*。这些是应用程序内部的异常条件,应用程序通常无法预测或恢复。这些通常表示编程错误,例如逻辑错误或 API 的不当使用。例如,考虑前面描述的应用程序将文件名传递给`FileReader`的构造器。如果逻辑错误导致`null`传递给构造器,构造器将抛出`NullPointerException`。应用程序可以捕获此异常,但消除导致异常发生的错误可能更有意义。
运行时异常 _ 不受[捕获或指定要求]_ 的约束。运行时异常是`RuntimeException`及其子类指示的异常。
运行时异常*不受[捕获或指定要求]_ 的约束。运行时异常是`RuntimeException`及其子类指示的异常。
错误和运行时异常统称为 _ 未经检查的异常 _
错误和运行时异常统称为*未经检查的异常*
## 绕过 Catch 或指定
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/concepts/object.html](https://docs.oracle.com/javase/tutorial/java/concepts/object.html)
对象是理解 _ 面向对象 _ 技术的关键。现在环顾四周,你会发现许多真实物体的例子:你的狗,你的桌子,你的电视机,你的自行车。
对象是理解*面向对象*技术的关键。现在环顾四周,你会发现许多真实物体的例子:你的狗,你的桌子,你的电视机,你的自行车。
真实世界的物体共有两个特征:它们都具有 _ 状态 _ 和 _ 行为 _。狗有状态(名称,颜色,品种,饥饿)和行为(吠叫,取出,摇尾)。自行车还具有状态(当前档位,当前踏板节奏,当前速度)和行为(改变档位,改变踏板节奏,应用制动器)。识别真实世界对象的状态和行为是开始思考面向对象编程的好方法。
真实世界的物体共有两个特征:它们都具有*状态**行为*。狗有状态(名称,颜色,品种,饥饿)和行为(吠叫,取出,摇尾)。自行车还具有状态(当前档位,当前踏板节奏,当前速度)和行为(改变档位,改变踏板节奏,应用制动器)。识别真实世界对象的状态和行为是开始思考面向对象编程的好方法。
现在花点时间观察您附近区域的真实物体。对于您看到的每个对象,请问自己两个问题:“这个对象可能存在哪些状态?”和“这个对象可以执行什么样的行为?”。一定要记下你的观察结果。和你一样,你会发现现实世界的物体的复杂程度各不相同;您的桌面灯可能只有两种可能的状态(打开和关闭)和两种可能的行为(打开,关闭),但您的桌面电台可能有其他状态(开,关,当前音量,当前电台)和行为(打开) ,关闭,增加音量,减少音量,搜索,扫描和调整)。您可能还会注意到,某些对象反过来也会包含其他对象。这些现实世界的观察都转化为面向对象编程的世界。
......@@ -14,7 +14,7 @@
软件对象在概念上类似于现实世界的对象:它们也包括状态和相关行为。对象将其状态存储在 _ 字段 _(某些编程语言中的变量)中,并通过 _ 方法 _(某些编程语言中的函数)公开其行为。方法对对象的内部状态进行操作,并作为对象到对象通信的主要机制。隐藏内部状态并要求通过对象的方法执行所有交互被称为 _ 数据封装 _ - 面向对象编程的基本原则。
软件对象在概念上类似于现实世界的对象:它们也包括状态和相关行为。对象将其状态存储在*字段*(某些编程语言中的变量)中,并通过*方法*(某些编程语言中的函数)公开其行为。方法对对象的内部状态进行操作,并作为对象到对象通信的主要机制。隐藏内部状态并要求通过对象的方法执行所有交互被称为*数据封装 _ - 面向对象编程的基本原则。
考虑一下自行车,例如:
......@@ -31,4 +31,4 @@
1. 模块化:可以独立于其他对象的源代码编写和维护对象的源代码。一旦创建,对象就可以轻松地在系统内部传递。
2. 信息隐藏:通过仅与对象的方法交互,其内部实现的细节仍然隐藏在外部世界之外。
3. 代码重用:如果对象已存在(可能由其他软件开发人员编写),则可以在程序中使用该对象。这允许专家实现/测试/调试复杂的,特定于任务的对象,然后您可以信任这些对象在您自己的代码中运行。
4. 可插拔性和调试简便性:如果某个特定对象有问题,您只需将其从应用程序中删除,然后插入另一个对象作为替代对象。这类似于解决现实世界中的机械问题。如果螺栓断裂,则将 _ 替换为 _,而不是整个机器。
\ No newline at end of file
4. 可插拔性和调试简便性:如果某个特定对象有问题,您只需将其从应用程序中删除,然后插入另一个对象作为替代对象。这类似于解决现实世界中的机械问题。如果螺栓断裂,则将*替换为*,而不是整个机器。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html)
`try`程序段退出时,`finally`程序段 _ 始终 _ 执行。这确保即使发生意外异常也会执行`finally`块。但是`finally`不仅仅用于异常处理 - 它允许程序员避免被`return``continue``break`意外绕过清理代码。将清理代码放在`finally`块中始终是一种很好的做法,即使没有预期的例外情况也是如此。
`try`程序段退出时,`finally`程序段*始终*执行。这确保即使发生意外异常也会执行`finally`块。但是`finally`不仅仅用于异常处理 - 它允许程序员避免被`return``continue``break`意外绕过清理代码。将清理代码放在`finally`块中始终是一种很好的做法,即使没有预期的例外情况也是如此。
* * *
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)
`try` -with-resources 语句是声明一个或多个资源的`try`语句。 _ 资源 _ 是一个在程序完成后必须关闭的对象。 `try` -with-resources 语句确保在语句结束时关闭每个资源。实现`java.lang.AutoCloseable`的任何对象(包括实现`java.io.Closeable`的所有对象)都可以用作资源。
`try` -with-resources 语句是声明一个或多个资源的`try`语句。*资源*是一个在程序完成后必须关闭的对象。 `try` -with-resources 语句确保在语句结束时关闭每个资源。实现`java.lang.AutoCloseable`的任何对象(包括实现`java.io.Closeable`的所有对象)都可以用作资源。
以下示例从文件中读取第一行。它使用`BufferedReader`实例从文件中读取数据。 `BufferedReader`是程序完成后必须关闭的资源:
......@@ -71,7 +71,7 @@ public static void writeToFileZipFileContents(String zipFileName,
```
在此示例中,`try` -with-resources 语句包含两个以分号分隔的声明:`ZipFile``BufferedWriter`。当直接跟随它的代码块正常或由于异常终止时,`BufferedWriter``ZipFile`对象的`close`方法将按此顺序自动调用。请注意,资源的`close`方法在它们创建的 _ 相反 _ 顺序中调用。
在此示例中,`try` -with-resources 语句包含两个以分号分隔的声明:`ZipFile``BufferedWriter`。当直接跟随它的代码块正常或由于异常终止时,`BufferedWriter``ZipFile`对象的`close`方法将按此顺序自动调用。请注意,资源的`close`方法在它们创建的*相反*顺序中调用。
以下示例使用`try` -with-resources 语句自动关闭`java.sql.Statement`对象:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html)
上一节介绍了如何为`ListOfNumbers`类中的`writeList`方法编写异常处理器。有时,代码可以捕获可能在其中发生的异常。但是,在其他情况下,最好让调用堆栈中的方法进一步处理异常。例如,如果您将`ListOfNumbers`类作为类包的一部分提供,则可能无法预测包的所有用户的需求。在这种情况下,最好 _ 而不是 _ 捕获异常并允许进一步调用堆栈的方法来处理它。
上一节介绍了如何为`ListOfNumbers`类中的`writeList`方法编写异常处理器。有时,代码可以捕获可能在其中发生的异常。但是,在其他情况下,最好让调用堆栈中的方法进一步处理异常。例如,如果您将`ListOfNumbers`类作为类包的一部分提供,则可能无法预测包的所有用户的需求。在这种情况下,最好*而不是*捕获异常并允许进一步调用堆栈的方法来处理它。
如果`writeList`方法没有捕获可能在其中发生的已检查异常,则`writeList`方法必须指定它可以抛出这些异常。让我们修改原始的`writeList`方法来指定它可以抛出而不是捕获它们的异常。提醒您,这是无法编译的`writeList`方法的原始版本。
......
......@@ -8,7 +8,7 @@
您还可以创建自己的异常类来表示您编写的类中可能出现的问题。实际上,如果您是程序包开发人员,则可能必须创建自己的一组异常类,以允许用户将程序包中可能发生的错误与 Java 平台或其他程序包中发生的错误区分开来。
您还可以创建 _ 链式 _ 例外。有关更多信息,请参阅[链式异常](../../essential/exceptions/chained.html)部分。
您还可以创建*链式*例外。有关更多信息,请参阅[链式异常](../../essential/exceptions/chained.html)部分。
## 抛出声明
......@@ -53,7 +53,7 @@ Throwable 类。
## 错误类
当发生 Java 虚拟机中的动态链接故障或其他硬故障时,虚拟机将抛出`Error`。简单的程序通常会 _ 而不是 _ 捕获或抛出`Error`
当发生 Java 虚拟机中的动态链接故障或其他硬故障时,虚拟机将抛出`Error`。简单的程序通常会*而不是*捕获或抛出`Error`
## 例外类
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/exceptions/chained.html](https://docs.oracle.com/javase/tutorial/essential/exceptions/chained.html)
应用程序通常会通过抛出另一个异常来响应异常。实际上,第一个例外 _ 导致 _ 第二个例外。了解一个异常何时导致另一个异常非常有用。 _ 链式异常 _ 帮助程序员做到这一点。
应用程序通常会通过抛出另一个异常来响应异常。实际上,第一个例外*导致*第二个例外。了解一个异常何时导致另一个异常非常有用。*链式异常*帮助程序员做到这一点。
以下是`Throwable`中支持链式异常的方法和构造器。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/concepts/class.html](https://docs.oracle.com/javase/tutorial/java/concepts/class.html)
在现实世界中,您经常会发现许多相同类型的单个对象。可能存在数千种其他自行车,所有相同的品牌和型号。每辆自行车都是使用相同的蓝图构建的,因此包含相同的组件。在面向对象的术语中,我们说你的自行车是类物体的 _ 实例 _,被称为自行车。 _ 类 _ 是创建单个对象的蓝图。
在现实世界中,您经常会发现许多相同类型的单个对象。可能存在数千种其他自行车,所有相同的品牌和型号。每辆自行车都是使用相同的蓝图构建的,因此包含相同的组件。在面向对象的术语中,我们说你的自行车是类物体的*实例*,被称为自行车。*类*是创建单个对象的蓝图。
以下 [`Bicycle`](examples/Bicycle.java) 类是自行车的一种可能实现方式:
......@@ -40,7 +40,7 @@ class Bicycle {
Java 编程语言的语法对您来说很新,但这个类的设计基于之前对自行车对象的讨论。字段`cadence``speed``gear`表示对象的状态,方法(`changeCadence``changeGear``speedUp`等)定义其与外部世界的交互。
您可能已经注意到`Bicycle`类不包含`main`方法。那是因为它不是一个完整的应用程序;它只是自行车的蓝图,可能是 _ 在应用程序中使用 _。创建和使用新`Bicycle`对象的责任属于应用程序中的其他类。
您可能已经注意到`Bicycle`类不包含`main`方法。那是因为它不是一个完整的应用程序;它只是自行车的蓝图,可能是*在应用程序中使用*。创建和使用新`Bicycle`对象的责任属于应用程序中的其他类。
这是一个 [`BicycleDemo`](examples/BicycleDemo.java) 类,它创建两个独立的`Bicycle`对象并调用它们的方法:
......
......@@ -10,7 +10,7 @@
运行时异常可以在程序中的任何地方发生,而在典型的程序中,它们可以非常多。必须在每个方法声明中添加运行时异常会降低程序的清晰度。因此,编译器不要求您捕获或指定运行时异常(尽管您可以)。
抛出`RuntimeException`的常见做法的一种情况是当用户错误地调用方法时。例如,一个方法可以检查其中一个参数是否错误`null`。如果参数是`null`,则该方法可能抛出`NullPointerException`,这是 _ 未检查 _ 异常。
抛出`RuntimeException`的常见做法的一种情况是当用户错误地调用方法时。例如,一个方法可以检查其中一个参数是否错误`null`。如果参数是`null`,则该方法可能抛出`NullPointerException`,这是*未检查*异常。
一般来说,不要抛出`RuntimeException`或创建`RuntimeException`的子类,因为你不想被指定你的方法可以抛出的异常所困扰。
......
......@@ -12,4 +12,4 @@
`try`语句应包含至少一个`catch`块或`finally`块,并且可能包含多个`catch`块。
异常对象的类指示抛出的异常类型。异常对象可以包含有关错误的更多信息,包括错误消息。对于异常链接,异常可以指向导致它的异常,这可以反过来指向导致 _ 它 _ 的异常,依此类推。
\ No newline at end of file
异常对象的类指示抛出的异常类型。异常对象可以包含有关错误的更多信息,包括错误消息。对于异常链接,异常可以指向导致它的异常,这可以反过来指向导致*它*的异常,依此类推。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/index.html](https://docs.oracle.com/javase/tutorial/essential/io/index.html)
本课程介绍用于基本 I / O 的 Java 平台类。它首先关注 _I / O 流 _,这是一个强大的概念,可以大大简化 I / O 操作。本课程还介绍了序列化,它允许程序将整个对象写入流并再次读回。然后,本课将介绍文件 I / O 和文件系统操作,包括随机访问文件。
本课程介绍用于基本 I / O 的 Java 平台类。它首先关注 _I / O 流*,这是一个强大的概念,可以大大简化 I / O 操作。本课程还介绍了序列化,它允许程序将整个对象写入流并再次读回。然后,本课将介绍文件 I / O 和文件系统操作,包括随机访问文件。
`I/O Streams`部分涵盖的大多数类都在`java.io`包中。 `File I/O`部分涵盖的大多数类都在`java.nio.file`包中。
......
......@@ -2,11 +2,11 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/streams.html](https://docs.oracle.com/javase/tutorial/essential/io/streams.html)
_I / O 流 _ 表示输入源或输出目的地。流可以表示许多不同类型的源和目标,包括磁盘文件,设备,其他程序和内存阵列。
_I / O 流*表示输入源或输出目的地。流可以表示许多不同类型的源和目标,包括磁盘文件,设备,其他程序和内存阵列。
Streams 支持许多不同类型的数据,包括简单字节,原始数据类型,本地化字符和对象。有些流只传递数据;其他人以有用的方式操纵和转换数据。
无论它们如何在内部工作,所有流都为使用它们的程序提供相同的简单模型:流是一系列数据。程序使用 _ 输入流 _ 从源读取数据,一次一个项目:
无论它们如何在内部工作,所有流都为使用它们的程序提供相同的简单模型:流是一系列数据。程序使用*输入流*从源读取数据,一次一个项目:
![Reading information into a program.](img/8be93be95ea565ddec4a549d20ec976c.jpg)
......@@ -14,7 +14,7 @@ Streams 支持许多不同类型的数据,包括简单字节,原始数据类
程序使用 _ 输出流 _ 将数据写入目标,一次一个项目:
程序使用*输出流*将数据写入目标,一次一个项目:
![Writing information from a program.](img/f76b8c03f1edd2f06496f57fa7bbb906.jpg)
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html](https://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html)
程序使用 _ 字节流 _ 执行 8 位字节的输入和输出。所有字节流类都来自 [`InputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html)[`OutputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html)
程序使用*字节流*执行 8 位字节的输入和输出。所有字节流类都来自 [`InputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html)[`OutputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html)
有许多字节流类。为了演示字节流的工作原理,我们将重点关注文件 I / O 字节流, [`FileInputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html)[`FileOutputStream`](https://docs.oracle.com/javase/8/docs/api/java/io/FileOutputStream.html) 。其他种类的字节流的使用方式大致相同;它们的不同之处主要在于它们的构造方式。
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/buffers.html](https://docs.oracle.com/javase/tutorial/essential/io/buffers.html)
到目前为止,我们看到的大多数示例都使用 _ 无缓冲 _ I / O.这意味着每个读取或写入请求都由底层操作系统直接处理。这可以使程序效率低得多,因为每个这样的请求经常触发磁盘访问,网络活动或一些相对昂贵的其他操作。
到目前为止,我们看到的大多数示例都使用*无缓冲 _ I / O.这意味着每个读取或写入请求都由底层操作系统直接处理。这可以使程序效率低得多,因为每个这样的请求经常触发磁盘访问,网络活动或一些相对昂贵的其他操作。
为了减少这种开销,Java 平台实现了 _ 缓冲的 _ I / O 流。缓冲输入流从称为 _ 缓冲区 _ 的存储区读取数据;仅当缓冲区为空时才调用本机输入 API。类似地,缓冲输出流将数据写入缓冲区,并且仅在缓冲区已满时才调用本机输出 API。
为了减少这种开销,Java 平台实现了*缓冲的 _ I / O 流。缓冲输入流从称为*缓冲区*的存储区读取数据;仅当缓冲区为空时才调用本机输入 API。类似地,缓冲输出流将数据写入缓冲区,并且仅在缓冲区已满时才调用本机输出 API。
程序可以使用我们现在多次使用的包装习惯用法将无缓冲的流转换为缓冲流,其中无缓冲的流对象被传递给缓冲流类的构造器。以下是如何修改`CopyCharacters`示例中的构造器调用以使用缓冲 I / O:
......@@ -18,7 +18,7 @@ outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));
## 刷新缓冲流
在关键点写出缓冲区通常是有意义的,而无需等待它填充。这被称为 _ 冲洗 _ 缓冲液。
在关键点写出缓冲区通常是有意义的,而无需等待它填充。这被称为*冲洗*缓冲液。
一些缓冲输出类支持 _autoflush_ ,由可选的构造器参数指定。启用 autoflush 时,某些键事件会导致刷新缓冲区。例如,autoflush `PrintWriter`对象在`println``format`的每次调用时刷新缓冲区。有关这些方法的更多信息,请参见[格式化](formatting.html)
......
......@@ -4,7 +4,7 @@
不同种类的物体通常彼此具有一定的共同量。例如,山地自行车,公路自行车和双人自行车都具有自行车的特性(当前速度,当前踏板节奏,当前档位)。然而,每个还定义了使它们与众不同的其他功能:双人自行车有两个座位和两套车把;公路自行车有把手下降;一些山地自行车有一个额外的链环,使它们的齿轮比更低。
面向对象编程允许类 _ 继承 _ 常用的其他类的状态和行为。在这个例子中,`Bicycle`现在变成`MountainBike``RoadBike``TandemBike`的 _ 超类 _。在 Java 编程语言中,每个类都允许有一个直接的超类,每个超类都有可能存在无限数量的 _ 子类 _
面向对象编程允许类*继承*常用的其他类的状态和行为。在这个例子中,`Bicycle`现在变成`MountainBike``RoadBike``TandemBike`*超类*。在 Java 编程语言中,每个类都允许有一个直接的超类,每个超类都有可能存在无限数量的*子类*
![A diagram of classes in a hierarchy.](img/a3b4c6e8955f9562ddc1a464806476e7.jpg)
......
......@@ -51,7 +51,7 @@ The square root of 5 is 2.23606797749979.
## `format`方法
`format`方法基于 _ 格式字符串 _ 格式化多个参数。格式字符串由嵌入 _ 格式说明符 _ 的静态文本组成;除格式说明符外,格式字符串输出不变。
`format`方法基于*格式字符串*格式化多个参数。格式字符串由嵌入*格式说明符*的静态文本组成;除格式说明符外,格式字符串输出不变。
格式字符串支持许多功能。在本教程中,我们将介绍一些基础知识。有关完整说明,请参阅 API 规范中的 [`format string syntax`](https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax)
......@@ -76,7 +76,7 @@ The square root of 2 is 1.414214.
```
与本例中使用的三个一样,所有格式说明符都以`%`开头,以 1 或 2 字符 _ 转换 _ 结束,指定生成的格式化输出的种类。这里使用的三个转换是:
与本例中使用的三个一样,所有格式说明符都以`%`开头,以 1 或 2 字符*转换*结束,指定生成的格式化输出的种类。这里使用的三个转换是:
* `d`将整数值格式化为十进制值。
* `f`将浮点值格式化为十进制值。
......
......@@ -8,7 +8,7 @@
标准流是许多操作系统的一个特性。默认情况下,他们从键盘读取输入并将输出写入显示器。它们还支持文件和程序之间的 I / O,但该功能由命令行解释器控制,而不是程序。
Java 平台支持三种标准流:_ 标准输入 _,通过`System.in`访问; _ 标准输出 _,通过`System.out`访问;和 _ 标准错误 _,通过`System.err`访问。这些对象是自动定义的,不需要打开。标准输出和标准误差均用于输出;单独具有错误输出允许用户将常规输出转移到文件并仍然能够读取错误消息。有关更多信息,请参阅命令行解释程序的文档。
Java 平台支持三种标准流:*标准输入*,通过`System.in`访问; _ 标准输出*,通过`System.out`访问;和*标准错误*,通过`System.err`访问。这些对象是自动定义的,不需要打开。标准输出和标准误差均用于输出;单独具有错误输出允许用户将常规输出转移到文件并仍然能够读取错误消息。有关更多信息,请参阅命令行解释程序的文档。
您可能希望标准流是字符流,但由于历史原因,它们是字节流。 `System.out``System.err`定义为 [`PrintStream`](https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html) 对象。虽然它在技术上是字节流,但`PrintStream`利用内部字符流对象来模拟字符流的许多功能。
......
......@@ -86,4 +86,4 @@ try {
`DataStreams`使用一种非常糟糕的编程技术:它使用浮点数来表示货币值。通常,浮点对于精确值是不利的。对于小数部分尤其如此,因为常见值(例如`0.1`)没有二进制表示。
用于货币值的正确类型是 [`java.math.BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) 。不幸的是,`BigDecimal`是一种对象类型,因此它不适用于数据流。但是,`BigDecimal` _ 将 _ 与对象流一起使用,这将在下一节中介绍。
\ No newline at end of file
用于货币值的正确类型是 [`java.math.BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) 。不幸的是,`BigDecimal`是一种对象类型,因此它不适用于数据流。但是,`BigDecimal` _ 将*与对象流一起使用,这将在下一节中介绍。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/path.html](https://docs.oracle.com/javase/tutorial/essential/io/path.html)
文件系统以某种形式存储和组织某种形式的媒体上的文件,通常是一个或多个硬盘驱动器,以便可以容易地检索它们。目前使用的大多数文件系统都将文件存储在树(或 _ 分层 _)结构中。在树的顶部是一个(或多个)根节点。在根节点下,有文件和目录(Microsoft Windows 中的 _ 文件夹 _)。每个目录都可以包含文件和子目录,而这些文件和子目录又可以包含文件和子目录,等等,可能达到几乎无限的深度。
文件系统以某种形式存储和组织某种形式的媒体上的文件,通常是一个或多个硬盘驱动器,以便可以容易地检索它们。目前使用的大多数文件系统都将文件存储在树(或*分层*)结构中。在树的顶部是一个(或多个)根节点。在根节点下,有文件和目录(Microsoft Windows 中的*文件夹*)。每个目录都可以包含文件和子目录,而这些文件和子目录又可以包含文件和子目录,等等,可能达到几乎无限的深度。
本节包括以下内容:
......@@ -32,15 +32,15 @@ C:\home\sally\statusReport
```
用于分隔目录名称的字符(也称为 _ 分隔符 _)特定于文件系统:Solaris OS 使用正斜杠(`/`),Microsoft Windows 使用反斜杠斜杠(`\` ])。
用于分隔目录名称的字符(也称为*分隔符*)特定于文件系统:Solaris OS 使用正斜杠(`/`),Microsoft Windows 使用反斜杠斜杠(`\` ])。
路径是 _ 相对 _ 或 _ 绝对 _。绝对路径始终包含查找文件所需的根元素和完整目录列表。例如,`/home/sally/statusReport`是绝对路径。查找文件所需的所有信息都包含在路径字符串中。
路径是*相对*或*绝对*。绝对路径始终包含查找文件所需的根元素和完整目录列表。例如,`/home/sally/statusReport`是绝对路径。查找文件所需的所有信息都包含在路径字符串中。
相对路径需要与另一个路径组合才能访问文件。例如,`joe/foo`是相对路径。如果没有更多信息,程序将无法在文件系统中可靠地找到`joe/foo`目录。
文件系统对象通常是目录或文件。每个人都熟悉这些对象。但是一些文件系统也支持符号链接的概念。符号链接也称为 _ 符号链接 _ 或 _ 软链接 _
文件系统对象通常是目录或文件。每个人都熟悉这些对象。但是一些文件系统也支持符号链接的概念。符号链接也称为*符号链接*或*软链接*
_ 符号链接 _ 是一个特殊文件,用作对另一个文件的引用。在大多数情况下,符号链接对应用程序是透明的,符号链接上的操作会自动重定向到链接的目标。 (指向的文件或目录称为链接的 _ 目标 _。)例外情况是删除符号链接或重命名,在这种情况下链接本身被删除,或重命名而不是目标链接。
_ 符号链接*是一个特殊文件,用作对另一个文件的引用。在大多数情况下,符号链接对应用程序是透明的,符号链接上的操作会自动重定向到链接的目标。 (指向的文件或目录称为链接的*目标*。)例外情况是删除符号链接或重命名,在这种情况下链接本身被删除,或重命名而不是目标链接。
在下图中,`logFile`似乎是用户的常规文件,但它实际上是`dir/logs/HomeLogFile`的符号链接。 `HomeLogFile`是链接的目标。
......@@ -52,7 +52,7 @@ Example of a Symbolic Link.
符号链接通常对用户是透明的。读取或写入符号链接与读取或写入任何其他文件或目录相同。
解析链接的短语 _ 意味着用文件系统中的实际位置替换符号链接。在该示例中,解析`logFile`产生`dir/logs/HomeLogFile`。_
解析链接的短语*意味着用文件系统中的实际位置替换符号链接。在该示例中,解析`logFile`产生`dir/logs/HomeLogFile`。_
在实际场景中,大多数文件系统都可以自由使用符号链接。偶尔,粗心创建的符号链接可能会导致循环引用。当链接的目标指向原始链接时,会发生循环引用。循环引用可能是间接引用:目录`a`指向目录`b`,它指向目录`c`,其中包含指向目录`a`的子目录。当程序递归地遍历目录结构时,循环引用可能会导致严重破坏。但是,此方案已被考虑,并且不会导致程序无限循环。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html](https://docs.oracle.com/javase/tutorial/essential/io/pathOps.html)
[`Path`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html) 类包括各种方法,可用于获取有关路径,访问路径元素,将路径转换为其他形式或提取路径部分的信息。还存在用于匹配路径字符串的方法和用于去除路径中的冗余的方法。本课程介绍了这些`Path`方法,有时称为 _ 语法 _ 操作,因为它们在路径上运行,不访问文件系统。
[`Path`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html) 类包括各种方法,可用于获取有关路径,访问路径元素,将路径转换为其他形式或提取路径部分的信息。还存在用于匹配路径字符串的方法和用于去除路径中的冗余的方法。本课程介绍了这些`Path`方法,有时称为*语法*操作,因为它们在路径上运行,不访问文件系统。
本节包括以下内容:
......@@ -186,7 +186,7 @@ try {
```
您可以使用`resolve`方法组合路径。传入 _ 部分路径 _,该路径不包含根元素,并且该部分路径将附加到原始路径。
您可以使用`resolve`方法组合路径。传入*部分路径*,该路径不包含根元素,并且该部分路径将附加到原始路径。
例如,请考虑以下代码段:
......@@ -213,7 +213,7 @@ Paths.get("foo").resolve("/home/joe");
```
编写文件 I / O 代码时的一个常见要求是能够构建从文件系统中的一个位置到另一个位置的路径。您可以使用`relativize`方法来满足此要求。此方法构造一个源自原始路径并在传入路径指定的位置结束的路径。新路径是 _ 相对于原始路径的 _
编写文件 I / O 代码时的一个常见要求是能够构建从文件系统中的一个位置到另一个位置的路径。您可以使用`relativize`方法来满足此要求。此方法构造一个源自原始路径并在传入路径指定的位置结束的路径。新路径是*相对于原始路径的*
例如,考虑定义为`joe`和`sally`的两个相对路径:
......
......@@ -92,11 +92,11 @@ Files.move(source,
多个`Files`方法(如`move`)可以在某些文件系统中以原子方式执行某些操作。
_ 原子文件操作 _ 是不能被中断或“部分”执行的操作。执行整个操作或操作失败。当您在文件系统的同一区域上运行多个进程时,这很重要,并且您需要保证每个进程都访问一个完整的文件。
_ 原子文件操作*是不能被中断或“部分”执行的操作。执行整个操作或操作失败。当您在文件系统的同一区域上运行多个进程时,这很重要,并且您需要保证每个进程都访问一个完整的文件。
许多文件 I / O 方法支持 _ 方法链 _ 的概念。
许多文件 I / O 方法支持*方法链*的概念。
您首先调用返回对象的方法。然后,您立即在 _ 上调用 _ 对象的方法,该对象返回另一个对象,依此类推。许多 I / O 示例使用以下技术:
您首先调用返回对象的方法。然后,您立即在*上调用*对象的方法,该对象返回另一个对象,依此类推。许多 I / O 示例使用以下技术:
```java
String value = Charset.defaultCharset().decode(buf).toString();
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/concepts/interface.html](https://docs.oracle.com/javase/tutorial/java/concepts/interface.html)
正如您已经了解的那样,对象通过它们公开的方法定义它们与外部世界的交互。方法与外界形成对象的 _ 接口 _;例如,电视机正面的按钮是您与塑料外壳另一侧电线之间的接口。按“电源”按钮打开和关闭电视。
正如您已经了解的那样,对象通过它们公开的方法定义它们与外部世界的交互。方法与外界形成对象的*接口 _;例如,电视机正面的按钮是您与塑料外壳另一侧电线之间的接口。按“电源”按钮打开和关闭电视。
在最常见的形式中,接口是一组具有空体的相关方法。自行车的行为(如果指定为接口)可能如下所示:
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html](https://docs.oracle.com/javase/tutorial/essential/io/fileAttr.html)
_ 元数据 _ 的定义是“关于其他数据的数据”。使用文件系统,数据包含在其文件和目录中,元数据跟踪有关每个对象的信息:它是常规文件,目录还是链接?它的大小,创建日期,上次修改日期,文件所有者,组所有者和访问权限是什么?
_ 元数据*的定义是“关于其他数据的数据”。使用文件系统,数据包含在其文件和目录中,元数据跟踪有关每个对象的信息:它是常规文件,目录还是链接?它的大小,创建日期,上次修改日期,文件所有者,组所有者和访问权限是什么?
文件系统的元数据通常称为其 _ 文件属性 _`Files`类包括可用于获取文件的单个属性或设置属性的方法。
文件系统的元数据通常称为其*文件属性*`Files`类包括可用于获取文件的单个属性或设置属性的方法。
| 方法 | 评论 |
| --- | --- |
......@@ -29,7 +29,7 @@ _ 元数据 _ 的定义是“关于其他数据的数据”。使用文件系统
| [`readAttributes(Path, String, LinkOption...)`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAttributes-java.nio.file.Path-java.lang.String-java.nio.file.LinkOption...-) | 将文件的属性读取为批量操作。 `String`参数标识要读取的属性。 |
| [`readAttributes(Path, Class&lt;A&gt;, LinkOption...)`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#readAttributes-java.nio.file.Path-java.lang.Class-java.nio.file.LinkOption...-) | 将文件的属性读取为批量操作。 `Class&lt;A>`参数是请求的属性类型,该方法返回该类的对象。 |
在显示`readAttributes`方法的示例之前,应该提到的是,不同的文件系统对于应该跟踪哪些属性有不同的概念。因此,相关文件属性被组合在一起成为视图。 _ 视图 _ 映射到特定的文件系统实现,例如 POSIX 或 DOS,或者映射到常用功能,例如文件所有权。
在显示`readAttributes`方法的示例之前,应该提到的是,不同的文件系统对于应该跟踪哪些属性有不同的概念。因此,相关文件属性被组合在一起成为视图。*视图*映射到特定的文件系统实现,例如 POSIX 或 DOS,或者映射到常用功能,例如文件所有权。
支持的视图如下:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/rafs.html](https://docs.oracle.com/javase/tutorial/essential/io/rafs.html)
_ 随机存取文件 _ 允许对文件内容进行非顺序或随机访问。要随机访问文件,请打开文件,查找特定位置,以及读取或写入该文件。
_ 随机存取文件*允许对文件内容进行非顺序或随机访问。要随机访问文件,请打开文件,查找特定位置,以及读取或写入该文件。
使用 [`SeekableByteChannel`](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SeekableByteChannel.html) 接口可以实现此功能。 `SeekableByteChannel`接口使用当前位置的概念扩展通道 I / O.使用方法可以设置或查询位置,然后可以从该位置读取数据或将数据写入该位置。 API 由一些易于使用的方法组成:
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/io/dirs.html](https://docs.oracle.com/javase/tutorial/essential/io/dirs.html)
前面讨论过的一些方法,如`delete`,适用于文件,链接 _ 和 _ 目录。但是如何列出文件系统顶部的所有目录?如何列出目录的内容或创建目录?
前面讨论过的一些方法,如`delete`,适用于文件,链接*和*目录。但是如何列出文件系统顶部的所有目录?如何列出目录的内容或创建目录?
本节介绍以下特定于目录的功能:
......
......@@ -4,7 +4,7 @@
如前所述,`java.nio.file`包,特别是`Path`类是“链路感知”。每个`Path`方法都会检测遇到符号链接时要执行的操作,或者它提供了一个选项,使您可以在遇到符号链接时配置行为。
到目前为止的讨论一直是[符号或 _ 软 _ 链接](path.html#symlink),但有些文件系统也支持硬链接。 _ 硬链接 _ 比符号链接更具限制性,如下所示:
到目前为止的讨论一直是[符号或*软*链接](path.html#symlink),但有些文件系统也支持硬链接。*硬链接*比符号链接更具限制性,如下所示:
* 链接的目标必须存在。
* 目录上通常不允许使用硬链接。
......@@ -39,7 +39,7 @@ try {
`FileAttributes` vararg 使您可以指定在创建链接时以原子方式设置的初始文件属性。但是,此参数仅供将来使用,目前尚未实现。
您可以使用 [`createLink(Path, Path)`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createLink-java.nio.file.Path-java.nio.file.Path-) 方法创建到现有文件的硬(或 _ 常规 _)链接。第二个`Path`参数定位现有文件,它必须存在或抛出`NoSuchFileException`。以下代码段显示了如何创建链接:
您可以使用 [`createLink(Path, Path)`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#createLink-java.nio.file.Path-java.nio.file.Path-) 方法创建到现有文件的硬(或*常规*)链接。第二个`Path`参数定位现有文件,它必须存在或抛出`NoSuchFileException`。以下代码段显示了如何创建链接:
```java
Path newLink = ...;
......
......@@ -108,7 +108,7 @@ Files.walkFileTree(startingDir, opts, Integer.MAX_VALUE, finder);
例如,如果您正在编写递归删除,则首先删除目录中的文件,然后再删除目录本身。在这种情况下,您删除`postVisitDirectory`中的目录。
如果您正在编写递归副本,则在尝试将文件复制到`visitFiles`之前,在`preVisitDirectory`中创建新目录(在`visitFiles`中)。如果要保留源目录的属性(类似于 UNIX `cp -p`命令),则需要在复制文件后在`postVisitDirectory`中执行 _[``Copy`` ](examples/Copy.java)示例显示了如何执行此操作。_
如果您正在编写递归副本,则在尝试将文件复制到`visitFiles`之前,在`preVisitDirectory`中创建新目录(在`visitFiles`中)。如果要保留源目录的属性(类似于 UNIX `cp -p`命令),则需要在复制文件后在`postVisitDirectory`中执行*[``Copy`` ](examples/Copy.java)示例显示了如何执行此操作。_
如果您正在编写文件搜索,则在`visitFile`方法中执行比较。此方法查找符合条件的所有文件,但找不到目录。如果要查找文件和目录,还必须在`preVisitDirectory``postVisitDirectory`方法中执行比较。 [``Find`` ](examples/Find.java)示例显示了如何执行此操作。
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/java/concepts/package.html](https://docs.oracle.com/javase/tutorial/java/concepts/package.html)
包是一个命名空间,用于组织一组相关的类和接口。从概念上讲,您可以将包视为与计算机上的不同文件夹类似。您可以将 HTML 页面保留在一个文件夹中,将图像保存在另一个文件夹中,将脚本或应因为用 Java 编程语言编写的软件可以由数百个或 _ 数千 _ 的各个类组成,所以通过将相关的类和接口放入包来保持组织是有意义的。
包是一个命名空间,用于组织一组相关的类和接口。从概念上讲,您可以将包视为与计算机上的不同文件夹类似。您可以将 HTML 页面保留在一个文件夹中,将图像保存在另一个文件夹中,将脚本或应因为用 Java 编程语言编写的软件可以由数百个或*数千*的各个类组成,所以通过将相关的类和接口放入包来保持组织是有意义的。
Java 平台提供了一个适合在您自己的应用程序中使用的庞大的类库(一组包)。该库称为“应用程序编程接口”,简称“API”。它的包代表了最常用于通用编程的任务。例如,`String`对象包含字符串的状态和行为; `File`对象允许程序员轻松创建,删除,检查,比较或修改文件系统上的文件; `Socket`对象允许创建和使用网络套接字;各种 GUI 对象控制按钮和复选框以及与图形用户界面相关的任何其他内容。有数以千计的课程可供选择。这使程序员可以专注于特定应用程序的设计,而不是使其工作所需的基础结构。
......
......@@ -10,7 +10,7 @@ jEdit Dialog Box Showing That a Modified File Is Detected
要实现此功能,称为 _ 文件更改通知 _,程序必须能够检测文件系统上相关目录的内容。一种方法是轮询文件系统以查找更改,但这种方法效率低下。它不能扩展到具有数百个要监视的打开文件或目录的应用程序。
要实现此功能,称为*文件更改通知*,程序必须能够检测文件系统上相关目录的内容。一种方法是轮询文件系统以查找更改,但这种方法效率低下。它不能扩展到具有数百个要监视的打开文件或目录的应用程序。
`java.nio.file`包提供文件更改通知 API,称为 Watch Service API。此 API 使您可以使用监视服务注册目录(或多个目录)。注册时,您告诉服务您感兴趣的事件类型:文件创建,文件删除或文件修改。当服务检测到感兴趣的事件时,它将被转发到注册的进程。已注册的进程有一个线程(或一个线程池),专门用于监视它已注册的任何事件。当一个事件进入时,它会根据需要进行处理。
......@@ -199,4 +199,4 @@ static <T> WatchEvent<T> cast(WatchEvent<?> event) {
Watch Service API 专为需要通知文件更改事件的应用程序而设计。它非常适合任何应用程序,如编辑器或 IDE,可能有许多打开的文件,需要确保文件与文件系统同步。它也非常适合监视目录的应用程序服务器,可能等待`.jsp``.jar`文件丢弃,以便部署它们。
此 API 是 _ 而非 _,用于索引硬盘驱动器。大多数文件系统实现都具有文件更改通知的本机支持。 Watch Service API 在可用的情况下利用此支持。但是,当文件系统不支持此机制时,Watch Service 将轮询文件系统,等待事件。
\ No newline at end of file
此 API 是*而非*,用于索引硬盘驱动器。大多数文件系统实现都具有文件更改通知的本机支持。 Watch Service API 在可用的情况下利用此支持。但是,当文件系统不支持此机制时,Watch Service 将轮询文件系统,等待事件。
\ No newline at end of file
......@@ -52,7 +52,7 @@ String separator = FileSystems.getDefault().getSeparator();
[`getSeparator`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getSeparator--) 方法还用于检索任何可用文件系统的路径分隔符。
文件系统具有一个或多个文件存储来保存其文件和目录。 _ 文件存储 _ 表示底层存储设备。在 UNIX 操作系统中,每个安装的文件系统都由文件存储表示。在 Microsoft Windows 中,每个卷都由文件存储表示:`C:`,`D:`,依此类推。
文件系统具有一个或多个文件存储来保存其文件和目录。*文件存储*表示底层存储设备。在 UNIX 操作系统中,每个安装的文件系统都由文件存储表示。在 Microsoft Windows 中,每个卷都由文件存储表示:`C:`,`D:`,依此类推。
要检索文件系统的所有文件存储列表,可以使用 [`getFileStores`](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html#getFileStores--) 方法。此方法返回`Iterable`,允许您使用增强的语句迭代所有根目录。
......
......@@ -2,6 +2,6 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html)
计算机用户理所当然地认为他们的系统一次可以做多件事。他们假设他们可以继续在文字处理器中工作,而其他应用程序则下载文件,管理打印队列和流式传输音频。即使是单个应用程序通常也希望一次完成多个任务。例如,流式音频应用程序必须同时从网络读取数字音频,解压缩,管理播放和更新其显示。即使文字处理器应始终准备好响应键盘和鼠标事件,无论重新格式化文本或更新显示有多繁忙。可以执行此类操作的软件称为 _ 并发 _ 软件。
计算机用户理所当然地认为他们的系统一次可以做多件事。他们假设他们可以继续在文字处理器中工作,而其他应用程序则下载文件,管理打印队列和流式传输音频。即使是单个应用程序通常也希望一次完成多个任务。例如,流式音频应用程序必须同时从网络读取数字音频,解压缩,管理播放和更新其显示。即使文字处理器应始终准备好响应键盘和鼠标事件,无论重新格式化文本或更新显示有多繁忙。可以执行此类操作的软件称为*并发*软件。
Java 平台的设计初衷是为了支持并发编程,在 Java 编程语言和 Java 类库中提供基本的并发支持。从 5.0 版开始,Java 平台还包含高级并发 API。本课程介绍了平台的基本并发支持,并总结了`java.util.concurrent`包中的一些高级 API。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html)
在并发编程中,有两个基本执行单元:_ 处理 _ 和 _ 线程 _。在 Java 编程语言中,并发编程主要涉及线程。但是,流程也很重要。
在并发编程中,有两个基本执行单元:*处理**线程*。在 Java 编程语言中,并发编程主要涉及线程。但是,流程也很重要。
计算机系统通常具有许多活动进程和线程。即使在只有一个执行核心的系统中也是如此,因此在任何给定时刻只有一个线程实际执行。通过称为时间切片的 OS 功能,在进程和线程之间共享单个核的处理时间。
......@@ -12,14 +12,14 @@
进程具有自包含的执行环境。进程通常具有完整的私有基本运行时资源集;特别是,每个进程都有自己的内存空间。
流程通常被视为程序或应用程序的同义词。但是,用户看到的单个应用程序实际上可能是一组协作进程。为了促进进程之间的通信,大多数操作系统都支持 _ 进程间通信 _(IPC)资源,例如管道和套接字。 IPC 不仅用于同一系统上的进程之间的通信,而且还用于不同系统上的进程。
流程通常被视为程序或应用程序的同义词。但是,用户看到的单个应用程序实际上可能是一组协作进程。为了促进进程之间的通信,大多数操作系统都支持*进程间通信*(IPC)资源,例如管道和套接字。 IPC 不仅用于同一系统上的进程之间的通信,而且还用于不同系统上的进程。
Java 虚拟机的大多数实现都作为单个进程运行。 Java 应用程序可以使用 [`ProcessBuilder`](https://docs.oracle.com/javase/8/docs/api/java/lang/ProcessBuilder.html) 对象创建其他进程。多进程应用程序超出了本课程的范围。
## 主题
线程有时被称为 _ 轻量级进程 _。进程和线程都提供执行环境,但创建新线程所需的资源比创建新进程要少。
线程有时被称为*轻量级进程*。进程和线程都提供执行环境,但创建新线程所需的资源比创建新进程要少。
线程存在于进程中 - 每个进程至少有一个进程。线程共享进程的资源,包括内存和打开文件。这使得有效但可能有问题的通信成为可能。
多线程执行是 Java 平台的基本特性。每个应用程序至少有一个线程 - 或几个,如果你计算“系统”线程,它们执行内存管理和信号处理等操作。但是从应用程序员的角度来看,你只需要一个线程,称为 _ 主线程 _。该线程具有创建其他线程的能力,我们将在下一节中进行演示。
\ No newline at end of file
多线程执行是 Java 平台的基本特性。每个应用程序至少有一个线程 - 或几个,如果你计算“系统”线程,它们执行内存管理和信号处理等操作。但是从应用程序员的角度来看,你只需要一个线程,称为*主线程*。该线程具有创建其他线程的能力,我们将在下一节中进行演示。
\ No newline at end of file
......@@ -5,6 +5,6 @@
每个线程与类 [`Thread`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html) 的实例相关联。使用`Thread`对象创建并发应用程序有两种基本策略。
* 要直接控制线程创建和管理,只需在每次应用程序需要启动异步任务时实例化`Thread`
* 要从应用程序的其余部分抽象线程管理,请将应用程序的任务传递给 _ 执行程序 _
* 要从应用程序的其余部分抽象线程管理,请将应用程序的任务传递给*执行程序*
本节介绍`Thread`对象的使用。执行器与其他[高级并发对象](highlevel.html)讨论。
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html)
_ 中断 _ 表示线程应该停止正在进行的操作并执行其他操作。由程序员决定线程如何响应中断,但线程终止是很常见的。这是本课程中强调的用法。
_ 中断*表示线程应该停止正在进行的操作并执行其他操作。由程序员决定线程如何响应中断,但线程终止是很常见的。这是本课程中强调的用法。
线程通过调用`Thread`对象上的 [`interrupt`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt--) 来发送中断,以便中断线程。为使中断机制正常工作,被中断的线程必须支持自己的中断。
......@@ -53,6 +53,6 @@ if (Thread.interrupted()) {
## 中断状态标志
中断机制使用称为 _ 中断状态 _ 的内部标志来实现。调用`Thread.interrupt`设置此标志。当线程通过调用静态方法`Thread.interrupted`检查中断时,中断状态被清除。非静态`isInterrupted`方法(由一个线程用于查询另一个线程的中断状态)不会更改中断状态标志。
中断机制使用称为*中断状态*的内部标志来实现。调用`Thread.interrupt`设置此标志。当线程通过调用静态方法`Thread.interrupted`检查中断时,中断状态被清除。非静态`isInterrupted`方法(由一个线程用于查询另一个线程的中断状态)不会更改中断状态标志。
按照惯例,任何通过抛出`InterruptedException`退出的方法都会清除中断状态。但是,通过调用`interrupt`的另一个线程,总是可以立即再次设置中断状态。
\ No newline at end of file
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html)
线程主要通过共享对字段的访问和参考字段引用的对象进行通信。这种通信形式非常有效,但可能出现两种错误:_ 线程干扰 _ 和 _ 内存一致性错误 _。防止这些错误所需的工具是 _ 同步 _
线程主要通过共享对字段的访问和参考字段引用的对象进行通信。这种通信形式非常有效,但可能出现两种错误:*线程干扰**内存一致性错误*。防止这些错误所需的工具是*同步*
但是,同步会引入 ,当两个或多个线程同时尝试访问同一资源时 _ 和 _ 会导致 Java 运行时执行一个或多个线程更慢,甚至暂停执行。 [饥饿和活锁](../../essential/concurrency/starvelive.html)是线程争用的形式。有关详细信息,请参阅[活力](../../essential/concurrency/liveness.html)部分。
但是,同步会引入 ,当两个或多个线程同时尝试访问同一资源时*和*会导致 Java 运行时执行一个或多个线程更慢,甚至暂停执行。 [饥饿和活锁](../../essential/concurrency/starvelive.html)是线程争用的形式。有关详细信息,请参阅[活力](../../essential/concurrency/liveness.html)部分。
本节包括以下主题:
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html)
_ 当不同的线程具有应该是相同数据的不一致视图时,会发生内存一致性错误 _。内存一致性错误的原因很复杂,超出了本教程的范围。幸运的是,程序员不需要详细了解这些原因。所需要的只是避免它们的策略。
_ 当不同的线程具有应该是相同数据的不一致视图时,会发生内存一致性错误*。内存一致性错误的原因很复杂,超出了本教程的范围。幸运的是,程序员不需要详细了解这些原因。所需要的只是避免它们的策略。
避免内存一致性错误的关键是理解 _ 发生在 _ 关系之前。这种关系只是保证一个特定语句的内存写入对另一个特定语句可见。要查看此内容,请考虑以下示例。假设定义并初始化了一个简单的`int`字段:
避免内存一致性错误的关键是理解*发生在*关系之前。这种关系只是保证一个特定语句的内存写入对另一个特定语句可见。要查看此内容,请考虑以下示例。假设定义并初始化了一个简单的`int`字段:
```java
int counter = 0;
......
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html)
Java 编程语言提供两种基本同步习语:_ 同步方法 _ 和 _ 同步语句 _。下两节将介绍两个同步语句中较为复杂的语句。本节介绍同步方法。
Java 编程语言提供两种基本同步习语:*同步方法**同步语句*。下两节将介绍两个同步语句中较为复杂的语句。本节介绍同步方法。
要使方法同步,只需将`synchronized`关键字添加到其声明中:
......@@ -28,7 +28,7 @@ public class SynchronizedCounter {
如果`count``SynchronizedCounter`的实例,那么使这些方法同步有两个影响:
* 首先,对同一对象的两个同步方法的调用不可能进行交错。当一个线程正在为对象执行同步方法时,所有其他线程调用同一对象的同步方法(暂停执行)直到第一个线程完成对象。
* 其次,当同步方法退出时,它会自动与 _ 建立与同一对象的同步方法的任何后续调用 _ 之前发生的关系。这可以保证对所有线程都可以看到对象状态的更改。
* 其次,当同步方法退出时,它会自动与*建立与同一对象的同步方法的任何后续调用*之前发生的关系。这可以保证对所有线程都可以看到对象状态的更改。
请注意,构造器无法同步 - 将`synchronized`关键字与构造器一起使用是语法错误。同步构造器没有意义,因为只有创建对象的线程在构造时才能访问它。
......
......@@ -2,9 +2,9 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html)
同步是围绕一个称为 _ 内在锁 _ 或 _ 监视器锁 _ 的内部实体构建的。 (API 规范通常将此实体简称为“监视器”。)内部锁在同步的两个方面都发挥作用:强制对对象状态进行独占访问,并建立对可见性至关重要的先发生关系。
同步是围绕一个称为*内在锁**监视器锁*的内部实体构建的。 (API 规范通常将此实体简称为“监视器”。)内部锁在同步的两个方面都发挥作用:强制对对象状态进行独占访问,并建立对可见性至关重要的先发生关系。
每个对象都有一个与之关联的内在锁。按照惯例,需要对对象字段进行独占和一致访问的线程必须 _ 在访问对象之前获取 _ 对象的内部锁定,然后 _ 释放 _ 内部锁定时使用它们。一个线程被认为 _ 拥有 _ 它获得锁定和释放锁定之间的内在锁定。只要一个线程拥有一个内部锁,没有其他线程可以获得相同的锁。另一个线程在尝试获取锁时将阻塞。
每个对象都有一个与之关联的内在锁。按照惯例,需要对对象字段进行独占和一致访问的线程必须*在访问对象之前获取*对象的内部锁定,然后*释放*内部锁定时使用它们。一个线程被认为*拥有*它获得锁定和释放锁定之间的内在锁定。只要一个线程拥有一个内部锁,没有其他线程可以获得相同的锁。另一个线程在尝试获取锁时将阻塞。
当线程释放内部锁时,在该操作与同一锁的任何后续获取之间建立先发生关系。
......@@ -16,7 +16,7 @@
## 同步语句
创建同步代码的另一种方法是使用 _ 同步语句 _。与 synchronized 方法不同,synchronized 语句必须指定提供内部锁的对象:
创建同步代码的另一种方法是使用*同步语句*。与 synchronized 方法不同,synchronized 语句必须指定提供内部锁的对象:
```java
public void addName(String name) {
......@@ -59,4 +59,4 @@ public class MsLunch {
## 可重入同步
回想一下,线程无法获取另一个线程拥有的锁。但是线程 _ 可以 _ 获得它已经拥有的锁。允许线程多次获取相同的锁定会启用 _ 可重入同步 _。这描述了一种情况,其中同步代码直接或间接地调用也包含同步代码的方法,并且两组代码使用相同的锁。在没有可重入同步的情况下,同步代码必须采取许多额外的预防措施,以避免线程导致自身阻塞。
\ No newline at end of file
回想一下,线程无法获取另一个线程拥有的锁。但是线程*可以*获得它已经拥有的锁。允许线程多次获取相同的锁定会启用*可重入同步*。这描述了一种情况,其中同步代码直接或间接地调用也包含同步代码的方法,并且两组代码使用相同的锁。在没有可重入同步的情况下,同步代码必须采取许多额外的预防措施,以避免线程导致自身阻塞。
\ No newline at end of file
......@@ -2,12 +2,12 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html)
在编程中,_ 原子 _ 动作是一次有效发生的动作。原子动作不能在中间停止:它要么完全发生,要么根本不发生。在动作完成之前,原子动作的副作用是不可见的。
在编程中,*原子*动作是一次有效发生的动作。原子动作不能在中间停止:它要么完全发生,要么根本不发生。在动作完成之前,原子动作的副作用是不可见的。
我们已经看到增量表达式,例如`c++`,不描述原子动作。即使非常简单的表达式也可以定义可以分解为其他操作的复杂操作。但是,您可以指定原子操作:
* 读取和写入对于引用变量和大多数原始变量(除`long``double`之外的所有类型)都是原子的。
* 读取和写入对于 _ 所有 _ 变量都是原子的`volatile`(_ 包括 _ `long``double`变量)。
* 读取和写入对于*所有*变量都是原子的`volatile`*包括 _ `long``double`变量)。
原子动作不能交错,因此可以使用它们而不必担心线程干扰。但是,这并不能消除所有同步原子操作的需要,因为仍然可能存在内存一致性错误。使用`volatile`变量可降低内存一致性错误的风险,因为对`volatile`变量的任何写入都会建立与之后读取同一变量的先发生关系。这意味着对`volatile`变量的更改始终对其他线程可见。更重要的是,它还意味着当线程读取`volatile`变量时,它不仅会看到`volatile`的最新更改,还会看到导致更改的代码的副作用。
......
......@@ -2,4 +2,4 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/liveness.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/liveness.html)
并发应用程序及时执行的能力称为 _ 活跃度 _。本节描述了最常见的活体问题,[死锁](deadlock.html),并继续简要介绍另外两个活体问题,[饥饿和活锁](starvelive.html)
\ No newline at end of file
并发应用程序及时执行的能力称为*活跃度*。本节描述了最常见的活体问题,[死锁](deadlock.html),并继续简要介绍另外两个活体问题,[饥饿和活锁](starvelive.html)
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html](https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html)
_ 死锁 _ 描述了两个或多个线程永远被阻塞,等待彼此的情况。这是一个例子。
_ 死锁*描述了两个或多个线程永远被阻塞,等待彼此的情况。这是一个例子。
阿方斯和加斯顿是朋友,也很有礼貌的信徒。严格的礼貌规则是,当你向朋友鞠躬时,你必须保持鞠躬,直到你的朋友有机会归还弓箭。不幸的是,这条规则没有考虑到两个朋友可能同时互相鞠躬的可能性。这个示例应用程序 [``Deadlock``](examples/Deadlock.java)模拟了这种可能性:
......
......@@ -10,4 +10,4 @@ _Starvation_ 描述了线程无法获得对共享资源的定期访问而无法
## 活锁
线程通常用于响应另一个线程的操作。如果另一个线程的动作也是对另一个线程的动作的响应,则可能导致 _ 活锁 _。与死锁一样,活锁线程无法取得进一步进展。但是,线程没有被阻塞 - 他们只是太忙于相互回应以恢复工作。这相当于两个试图在走廊里互相通过的人:Alphonse 向左移动让 Gaston 通过,而 Gaston 向右移动让 Alphonse 通过。看到他们仍然互相阻挡,Alphone 向右移动,而 Gaston 向左移动。他们还在互相阻挡,所以......
\ No newline at end of file
线程通常用于响应另一个线程的操作。如果另一个线程的动作也是对另一个线程的动作的响应,则可能导致*活锁*。与死锁一样,活锁线程无法取得进一步进展。但是,线程没有被阻塞 - 他们只是太忙于相互回应以恢复工作。这相当于两个试图在走廊里互相通过的人:Alphonse 向左移动让 Gaston 通过,而 Gaston 向右移动让 Alphonse 通过。看到他们仍然互相阻挡,Alphone 向右移动,而 Gaston 向左移动。他们还在互相阻挡,所以......
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册