提交 02931b26 编写于 作者: W wizardforcel

Merge branch 'master' of https://github.com/apachecn/jtn-zh

...@@ -12,9 +12,11 @@ Java Comparator 是用于排列 Java 对象的接口。 在“ java.util.compara ...@@ -12,9 +12,11 @@ Java Comparator 是用于排列 Java 对象的接口。 在“ java.util.compara
Java Comparator 类似于 Comparable 接口,但可用于表征交换排序顺序,其中 Comparable 可通过常规请求(如字典编排)进行排序。 Java Comparator 类似于 Comparable 接口,但可用于表征交换排序顺序,其中 Comparable 可通过常规请求(如字典编排)进行排序。
## ##
#### public int compare(Object obj1,Object obj2): ```java
public int compare(Object obj1, Object obj2)
```
如何使用 Java 比较器? 如何使用 Java 比较器?
...@@ -22,7 +24,7 @@ Java Comparator 类似于 Comparable 接口,但可用于表征交换排序顺 ...@@ -22,7 +24,7 @@ Java Comparator 类似于 Comparable 接口,但可用于表征交换排序顺
比较器接口具有两种技术的特征:compare()和 equals()。 出现了 compare()策略,着眼于请求的两个组成部分- 比较器接口具有两种技术的特征:compare()和 equals()。 出现了 compare()策略,着眼于请求的两个组成部分-
## 比较方法 ## `compare`方法
int compare(Object obj1,Object obj2) int compare(Object obj1,Object obj2)
...@@ -32,7 +34,7 @@ obj1 和 obj2 受到质疑。 如果文章相等,则此策略返回零。 如 ...@@ -32,7 +34,7 @@ obj1 和 obj2 受到质疑。 如果文章相等,则此策略返回零。 如
![](img/5bc3e122a9704c141357fc8a272d1863.jpg) ![](img/5bc3e122a9704c141357fc8a272d1863.jpg)
## 等于 ## `equals`方
出现了 equals()策略,用于测试文章是否与调用比较器相符- 出现了 equals()策略,用于测试文章是否与调用比较器相符-
......
...@@ -38,7 +38,7 @@ Internet 层是一组方法,协议和规范,用于在必要时通过网络 ...@@ -38,7 +38,7 @@ Internet 层是一组方法,协议和规范,用于在必要时通过网络
SMTP 代表简单邮件传输协议。 它是一种标准的 Internet 协议,用于跨 Internet 协议网络的电子邮件传输。 还有本身不是协议的 SMTPS。 SMTPS 本质上是受 SSL 保护的 SMTP 连接。 SMTP 代表简单邮件传输协议。 它是一种标准的 Internet 协议,用于跨 Internet 协议网络的电子邮件传输。 还有本身不是协议的 SMTPS。 SMTPS 本质上是受 SSL 保护的 SMTP 连接。
### 流行音乐 ### POP
POP 代表邮局协议,是本地电子邮件客户端用来通过 TCP / IP 连接从远程服务器检索电子邮件的应用程序层 Internet 标准协议。 POP 支持下载和删除访问远程邮箱的要求。 POP 代表邮局协议,是本地电子邮件客户端用来通过 TCP / IP 连接从远程服务器检索电子邮件的应用程序层 Internet 标准协议。 POP 支持下载和删除访问远程邮箱的要求。
...@@ -46,9 +46,9 @@ POP 代表邮局协议,是本地电子邮件客户端用来通过 TCP / IP 连 ...@@ -46,9 +46,9 @@ POP 代表邮局协议,是本地电子邮件客户端用来通过 TCP / IP 连
IMAP 代表 Internet 消息访问协议。 电子邮件客户端使用的一种 Internet 标准协议,它通过 TCP / IP 连接从邮件服务器检索电子邮件。 它还允许电子邮件客户端访问远程邮件服务器上的电子邮件。 传入的电子邮件被发送到电子邮件服务器,该服务器将消息存储在收件人的电子邮件框中。 IMAP 代表 Internet 消息访问协议。 电子邮件客户端使用的一种 Internet 标准协议,它通过 TCP / IP 连接从邮件服务器检索电子邮件。 它还允许电子邮件客户端访问远程邮件服务器上的电子邮件。 传入的电子邮件被发送到电子邮件服务器,该服务器将消息存储在收件人的电子邮件框中。
## JavaMail 体系结 ## JavaMail
现在该介绍 Java 邮件体系结构了。 现在该介绍 Java 邮件构了。
![How all components co-work](img/0a7b7b40c1703dea733475984347e26a.jpg) ![How all components co-work](img/0a7b7b40c1703dea733475984347e26a.jpg)
...@@ -64,7 +64,7 @@ IMAP 代表 Internet 消息访问协议。 电子邮件客户端使用的一种 ...@@ -64,7 +64,7 @@ IMAP 代表 Internet 消息访问协议。 电子邮件客户端使用的一种
![](img/e77ea03254e94151b64c80319e6a632c.jpg) ![](img/e77ea03254e94151b64c80319e6a632c.jpg)
### EmailSender.java ### `EmailSender.java`
要导入所有必需的库,您需要导入 4 件事。 要导入所有必需的库,您需要导入 4 件事。
......
# Java volatile 示例 # Java `volatile`示例
> 原文: [https://javatutorial.net/java-volatile-example](https://javatutorial.net/java-volatile-example) > 原文: [https://javatutorial.net/java-volatile-example](https://javatutorial.net/java-volatile-example)
在本教程中,我们将讨论 Java volatile 示例。 在本教程中,我们将讨论 Java volatile 示例。
## 什么是 Java volatile ## 什么是 Java `volatile`
Java volatile 关键字用于检查 Java 变量是否为“被存放在基本内存中”。 更具决定性的意义是,将无法从 PC 的主内存中读取每次无法预测的变量,而不是从 CPU 储备中读取,并且每次与不稳定变量保持联系都将与基本内存保持联系,而不是 只需到 CPU 存储。 Java volatile 关键字用于检查 Java 变量是否为“被存放在基本内存中”。 更具决定性的意义是,将无法从 PC 的主内存中读取每次无法预测的变量,而不是从 CPU 储备中读取,并且每次与不稳定变量保持联系都将与基本内存保持联系,而不是 只需到 CPU 存储。
实际上,由于 Java 5,不稳定的标语确保了除了不可预测因素之外还可以从基本内存中读取内容。 我将在随附领域中对此进行澄清。 实际上,由于 Java 5,不稳定的标语确保了除了不可预测因素之外还可以从基本内存中读取内容。 我将在随附领域中对此进行澄清。
## 如何在 Java 中使用 volatile 关键字? ## 如何在 Java 中使用`volatile`关键字?
什么是 Java 中的 volatile 变量?何时使用 Java 中的 volatile 变量是 Java 访谈中众所周知的多字符串查询问题? 尽管有许多软件工程师认识到什么是易失性变量,但是他们在第二部分进行了轰炸,例如在 Java 中利用易失性变量的地方很少,因为在 Java 中很少有明确的理解和动手操作的易失性。 在本教学练习中,我们将通过简单说明 Java 中 volatile 变量的情况并检查何时使用 Java 中的 volatile 变量来解决此漏洞。 无论如何,Java 中不可预测的流行语被用作指向 Java 编译器和 Thread 的指针,这些编译器和 Thread 不存储该变量的估计值,而可靠地从主内存中仔细研究了该变量。 因此,如果您需要共享任何因执行而导致读写活动至关重要的因素,例如细读和写 int 或布尔变量,则可以将它们声明为 volatile 变量。 什么是 Java 中的 volatile 变量?何时使用 Java 中的 volatile 变量是 Java 访谈中众所周知的多字符串查询问题? 尽管有许多软件工程师认识到什么是易失性变量,但是他们在第二部分进行了轰炸,例如在 Java 中利用易失性变量的地方很少,因为在 Java 中很少有明确的理解和动手操作的易失性。 在本教学练习中,我们将通过简单说明 Java 中 volatile 变量的情况并检查何时使用 Java 中的 volatile 变量来解决此漏洞。 无论如何,Java 中不可预测的流行语被用作指向 Java 编译器和 Thread 的指针,这些编译器和 Thread 不存储该变量的估计值,而可靠地从主内存中仔细研究了该变量。 因此,如果您需要共享任何因执行而导致读写活动至关重要的因素,例如细读和写 int 或布尔变量,则可以将它们声明为 volatile 变量。
...@@ -59,7 +59,7 @@ Java volatile 示例 ...@@ -59,7 +59,7 @@ Java volatile 示例
因此,在摘要中,与 Java 中的同步流行语分开,另外使用 volatile 关键字在字符串之间传递内存的内容。 因此,在摘要中,与 Java 中的同步流行语分开,另外使用 volatile 关键字在字符串之间传递内存的内容。
## 可变可见性问题 ## `volatile`可见性问题
Java 不稳定的流行语确保跨字符串的因素变化的可感知性。 这听起来可能有些消化,所以给我一个扩展的机会。 Java 不稳定的流行语确保跨字符串的因素变化的可感知性。 这听起来可能有些消化,所以给我一个扩展的机会。
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* 优化基础设施 * 优化基础设施
* 将应用程序及其依赖项打包到标准化单元中 * 将应用程序及其依赖项打包到标准化单元中
## 货柜 ## 容器
不,我不是在谈论现实世界中的容器。 但是,既然您正在考虑它,我不妨作个比喻。 现实生活中的容器的目的是存储需要运输到另一个地方的货物或物品。 现在,这些商品具有不同的存储要求,例如,可能存在牛奶的有效期比例如西红柿短的牛奶。 这就是为什么在现实生活中容器是非常有用的原因–容器保留了内部环境,例如敏感商品和/或物品的温度。 话虽如此,运输业不必担心这些物品,而将重点放在将它们从 A 运送到 B 上。 不,我不是在谈论现实世界中的容器。 但是,既然您正在考虑它,我不妨作个比喻。 现实生活中的容器的目的是存储需要运输到另一个地方的货物或物品。 现在,这些商品具有不同的存储要求,例如,可能存在牛奶的有效期比例如西红柿短的牛奶。 这就是为什么在现实生活中容器是非常有用的原因–容器保留了内部环境,例如敏感商品和/或物品的温度。 话虽如此,运输业不必担心这些物品,而将重点放在将它们从 A 运送到 B 上。
......
# 如何在 Windows 10 中设置 JAVA_HOME # 如何在 Windows 10 中设置`JAVA_HOME`
> 原文: [https://javatutorial.net/set-java-home-windows-10](https://javatutorial.net/set-java-home-windows-10) > 原文: [https://javatutorial.net/set-java-home-windows-10](https://javatutorial.net/set-java-home-windows-10)
在本教程中,我将向您展示如何**在 **Windows 10** 操作系统中将 JAVA_HOME** 设置为环境变量。 在本教程中,我将向您展示如何**在 **Windows 10** 操作系统中将 JAVA_HOME** 设置为环境变量。
## 为什么需要设置 JAVA_HOME ## 为什么需要设置`JAVA_HOME`
许多基于 Java 的程序(例如 Tomcat)都要求将 JAVA_HOME 设置为环境变量才能正常工作。 请注意 JAVA_HOME 应该指向一个 JDK 目录而不是 JRE 目录。 设置环境变量的目的是让程序知道可以在其中找到诸如 javac 之类的目录可执行文件。 许多基于 Java 的程序(例如 Tomcat)都要求将 JAVA_HOME 设置为环境变量才能正常工作。 请注意 JAVA_HOME 应该指向一个 JDK 目录而不是 JRE 目录。 设置环境变量的目的是让程序知道可以在其中找到诸如 javac 之类的目录可执行文件。
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
在 Windows 10 中搜索高级系统设置 在 Windows 10 中搜索高级系统设置
## 2.设置 JAVA_HOME 环境变量 ## 2.设置`JAVA_HOME`环境变量
在“系统属性窗口”中,单击“环境变量...” 在“系统属性窗口”中,单击“环境变量...”
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
取消部署应用程序就像逆转流程一样简单。 只需从`webapp`目录中删除`.war`文件,稍后 Tomcat 会为您清除所有解压缩的文件。 取消部署应用程序就像逆转流程一样简单。 只需从`webapp`目录中删除`.war`文件,稍后 Tomcat 会为您清除所有解压缩的文件。
## 使用 Tomcat Manager 部署和取消部署应用程序 ## 使用 Tomcat 管理器部署和取消部署应用程序
您可以使用图形管理器界面来部署或取消部署应用程序。 如果您没有启用管理器,则可以在我们之前的 [Tomcat 配置](https://javatutorial.net/how-to-install-and-configure-tomcat-8)教程中了解更多有关如何执行此操作的信息。 您可以使用图形管理器界面来部署或取消部署应用程序。 如果您没有启用管理器,则可以在我们之前的 [Tomcat 配置](https://javatutorial.net/how-to-install-and-configure-tomcat-8)教程中了解更多有关如何执行此操作的信息。
......
...@@ -130,7 +130,7 @@ public class SimpleServlet extends HttpServlet { ...@@ -130,7 +130,7 @@ public class SimpleServlet extends HttpServlet {
当 Web 容器终止 Servlet 时,将调用 **destroy()**方法。 我们可以使用这种方法来关闭与数据库或其他开放资源的连接。 当 Web 容器终止 Servlet 时,将调用 **destroy()**方法。 我们可以使用这种方法来关闭与数据库或其他开放资源的连接。
## 创建 web.xml 部署描述符 ## 创建`web.xml`部署描述符
`web.xml`文件用于告诉 Web 容器如何处理 Web 应用程序中的文件。 将其视为配置文件。 `web.xml`文件用于告诉 Web 容器如何处理 Web 应用程序中的文件。 将其视为配置文件。
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
Servlet POST 示例项目结构 Servlet POST 示例项目结构
## [Maven](https://javatutorial.net/how-to-install-maven-on-windows-linux-and-mac) pom.xml 文件 ## `pom.xml`文件
```java ```java
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...@@ -80,7 +80,7 @@ Servlet POST 示例项目结构 ...@@ -80,7 +80,7 @@ Servlet POST 示例项目结构
与上一教程一样,我们将 Servlet 的依赖项`javax.servlet-api``maven-war-plugin`的依赖关系用于构建网络应用 与上一教程一样,我们将 Servlet 的依赖项`javax.servlet-api``maven-war-plugin`的依赖关系用于构建网络应用
## 在 web.xml 文件中映射 Servlet ## 在`web.xml`文件中映射 Servlet
```java ```java
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
......
# Servlet 注示例 # Servlet 注示例
> 原文: [https://javatutorial.net/servlet-annotation-example](https://javatutorial.net/servlet-annotation-example) > 原文: [https://javatutorial.net/servlet-annotation-example](https://javatutorial.net/servlet-annotation-example)
本示例演示了注的用法,以便配置 Servlet。 本示例演示了注的用法,以便配置 Servlet。
在之前的教程中,我们使用部署描述符(web.xml 文件)来配置我们的 servlet。 从 Servlet 3.0 开始,您可以改用@WebServlet 批注。 该注释使您可以为 servlet 设置几个属性,例如名称,URL 等。 在之前的教程中,我们使用部署描述符(web.xml 文件)来配置我们的 servlet。 从 Servlet 3.0 开始,您可以改用@WebServlet 注解。 该注解使您可以为 servlet 设置几个属性,例如名称,URL 等。
## 注与部署描述符 ## 注与部署描述符
有什么不同? 好吧,很明显,部署描述符是一个单独的文件,您可以在其中以 XML 格式设置配置值,其中注释直接嵌入到源代码中。 如果您希望将代码和配置放在同一位置以提高可读性,请使用注释。 部署描述符恰恰相反-您将代码和配置分开。 这样,如果您要更改单个配置值,则无需重新编译整个项目。 有什么不同? 好吧,很明显,部署描述符是一个单独的文件,您可以在其中以 XML 格式设置配置值,其中注解直接嵌入到源代码中。 如果您希望将代码和配置放在同一位置以提高可读性,请使用注解。 部署描述符恰恰相反-您将代码和配置分开。 这样,如果您要更改单个配置值,则无需重新编译整个项目。
对于许多 Java Enterprise 组件,都有两个版本可用-注释或描述符。 但其他配置则只能使用批注或通过部署描述符进行配置。 对于 Servlet,可以选择一种或另一种方法。 对于许多 Java Enterprise 组件,都有两个版本可用-注解或描述符。 但其他配置则只能使用注解或通过部署描述符进行配置。 对于 Servlet,可以选择一种或另一种方法。
## WebServlet 注属性 ## WebServlet 注属性
您可以选择几种属性来配置 Servlet。 您可以选择几种属性来配置 Servlet。
### ###
* **值****urlPatterns** `String[]` –指定该 servlet 的一个或多个 URL 模式。 可以使用任何一个属性,但不能同时使用。 urlPatterns 的默认值为{},默认值为“” * **值****urlPatterns** `String[]` –指定该 servlet 的一个或多个 URL 模式。 可以使用任何一个属性,但不能同时使用。 urlPatterns 的默认值为{},默认值为“”
### 可选 ### 可选
* **asyncSupported** `boolean` –声明 Servlet 是否支持异步操作模式。 默认值为假 * **asyncSupported** `boolean` –声明 Servlet 是否支持异步操作模式。 默认值为假
* **名称** `String` – Servlet 的名称。 默认值为“” * **名称** `String` – Servlet 的名称。 默认值为“”
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
* **smallIcon** `String` – Servlet 的小图标。 默认值为“” * **smallIcon** `String` – Servlet 的小图标。 默认值为“”
* **loadOnStartup** int – Servlet 的启动时加载顺序。 默认值为-1 * **loadOnStartup** int – Servlet 的启动时加载顺序。 默认值为-1
## [Maven](https://javatutorial.net/how-to-install-maven-on-windows-linux-and-mac) 用于 Servlet 的 POM 文件 ## 用于 Servlet 的 POM 文件
我们将使用以下 pom.xml 文件构建本教程后面显示的示例。 我们将使用以下 pom.xml 文件构建本教程后面显示的示例。
...@@ -89,9 +89,9 @@ ...@@ -89,9 +89,9 @@
``` ```
## 使用批注时是否需要 web.xml ## 使用注解时是否需要`web.xml`
简短答案–不! 如果您选择对所有 Servlet 配置依赖注,则可以完全删除 web.xml 文件。 但我仍然鼓励您保留该文件,或者至少保留一个如以下示例所示的文件。 Web.xml 用于许多其他配置,因此您迟早需要在项目中使用它。 简短答案–不! 如果您选择对所有 Servlet 配置依赖注,则可以完全删除 web.xml 文件。 但我仍然鼓励您保留该文件,或者至少保留一个如以下示例所示的文件。 Web.xml 用于许多其他配置,因此您迟早需要在项目中使用它。
```java ```java
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
...@@ -118,9 +118,9 @@ ...@@ -118,9 +118,9 @@
</plugin> </plugin>
``` ```
## 用一个 URL 模式注的 Servlet ## 用一个 URL 模式注的 Servlet
以下示例仅使用一个属性来注 servlet 的 URL。 假设您在本地主机上运行应用程序并将其作为 servletannotation.war 部署,则 servlet 的路径将为 http:// localhost:8080 / servletannotation / hello 以下示例仅使用一个属性来注 servlet 的 URL。 假设您在本地主机上运行应用程序并将其作为 servletannotation.war 部署,则 servlet 的路径将为 http:// localhost:8080 / servletannotation / hello
```java ```java
package net.javatutorial.tutorials; package net.javatutorial.tutorials;
...@@ -148,7 +148,7 @@ public class ServletWithAnnotations extends HttpServlet { ...@@ -148,7 +148,7 @@ public class ServletWithAnnotations extends HttpServlet {
``` ```
## 具有多个属性的 Servlet 注 ## 具有多个属性的 Servlet 注
在此示例中,我们将设置 servlet 名称,URL 和 load-0n-startup 加载优先级。 在我们的[简单 Servlet 示例](https://javatutorial.net/java-servlet-example)中,我们在 web.xml 文件中执行了以下操作: 在此示例中,我们将设置 servlet 名称,URL 和 load-0n-startup 加载优先级。 在我们的[简单 Servlet 示例](https://javatutorial.net/java-servlet-example)中,我们在 web.xml 文件中执行了以下操作:
...@@ -175,7 +175,7 @@ public class ServletWithAnnotations extends HttpServlet { ...@@ -175,7 +175,7 @@ public class ServletWithAnnotations extends HttpServlet {
</web-app> </web-app>
``` ```
…现在我们将使用 WebServlet 批注实现相同的配置: …现在我们将使用 WebServlet 注解实现相同的配置:
```java ```java
package net.javatutorial.tutorials; package net.javatutorial.tutorials;
...@@ -203,7 +203,7 @@ public class ServletWithAnnotations extends HttpServlet { ...@@ -203,7 +203,7 @@ public class ServletWithAnnotations extends HttpServlet {
``` ```
## 具有多个 URL 模式的 Servlet 注 ## 具有多个 URL 模式的 Servlet 注
urlPatterns 属性接受一个数组作为值,因此您可以设置多个指向同一 servlet 的 URL: urlPatterns 属性接受一个数组作为值,因此您可以设置多个指向同一 servlet 的 URL:
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
## 注释与部署描述符 ## 注释与部署描述符
在前面的示例中,我们演示了使用[注释配置 Servlet](https://javatutorial.net/servlet-annotation-example) 的用法。 尽管您可以使用注释来设置 init 参数,但我不建议您这样做。 原因是,如果使用批注来设置初始化参数,则每次需要更改参数时都必须重新编译应用程序。 使用部署描述符来设置 init 参数要好得多。 一旦将 init 参数值放入 web.xml 文件中并需要更改它们,您要做的就是用更改后的值重新启动应用程序。 无需重新编译,无需重新部署! 在前面的示例中,我们演示了使用[注释配置 Servlet](https://javatutorial.net/servlet-annotation-example) 的用法。 尽管您可以使用注释来设置 init 参数,但我不建议您这样做。 原因是,如果使用注解来设置初始化参数,则每次需要更改参数时都必须重新编译应用程序。 使用部署描述符来设置 init 参数要好得多。 一旦将 init 参数值放入 web.xml 文件中并需要更改它们,您要做的就是用更改后的值重新启动应用程序。 无需重新编译,无需重新部署!
## @WebInitParam 批注 ## `@WebInitParam`注解
下面的示例显示 Servlet 声明中@WebInitParam 注释的用法 下面的示例显示 Servlet 声明中@WebInitParam 注释的用法
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
## Servlet 文件上传示例 ## Servlet 文件上传示例
Servlet 文件上载示例演示了 MultipartConfig 批注的用法,并使用户能够上载一个或两个文件。 Servlet 文件上载示例演示了 MultipartConfig 注解的用法,并使用户能够上载一个或两个文件。
该示例项目的结构非常简单。 它由一个 servlet 文件`FileUploadServlet.java``pom.xml`和可选的`web.xml`组成,这些文件用于在构建时处理依赖项。 正如我们在 [Servlet 注释示例](https://javatutorial.net/servlet-annotation-example)中讨论的那样,您可以在注释和部署描述符之间进行选择,以设置 Servlet 配置。 本示例使用注释。 该示例项目的结构非常简单。 它由一个 servlet 文件`FileUploadServlet.java``pom.xml`和可选的`web.xml`组成,这些文件用于在构建时处理依赖项。 正如我们在 [Servlet 注释示例](https://javatutorial.net/servlet-annotation-example)中讨论的那样,您可以在注释和部署描述符之间进行选择,以设置 Servlet 配置。 本示例使用注释。
...@@ -176,7 +176,7 @@ public class FileUploadServlet extends HttpServlet { ...@@ -176,7 +176,7 @@ public class FileUploadServlet extends HttpServlet {
``` ```
`@MultipatrtConfig`批注使 Servlet 可以接受文件上传。 有 3 个重要属性: `@MultipatrtConfig`注解使 Servlet 可以接受文件上传。 有 3 个重要属性:
* **fileSizeThreshold** –在将文件写入 temp 目录之前要超出的文件大小。 如果文件小于此阈值,则文件将在请求完成之前驻留在内存中。 * **fileSizeThreshold** –在将文件写入 temp 目录之前要超出的文件大小。 如果文件小于此阈值,则文件将在请求完成之前驻留在内存中。
* **maxFileSize** –这是允许上传的文件的最大大小。 在上面的示例中,不允许用户上传大于 10 MB 的文件 * **maxFileSize** –这是允许上传的文件的最大大小。 在上面的示例中,不允许用户上传大于 10 MB 的文件
......
...@@ -114,7 +114,7 @@ CREATE TABLE `user_groups` ( ...@@ -114,7 +114,7 @@ CREATE TABLE `user_groups` (
## 用户和组实体 ## 用户和组实体
在数据库中添加表`users``user_groups`后,必须为这两个表创建 JPA 实体。 实体会将数据库表映射到 Java 对象,因此您可以使用实体对象中的 getter 和 setter 方法轻松地修改或获取数据库。 使用@Entity 批注将 Java 类标记为实体。 该类还必须实现 Serializable 接口。 在数据库中添加表`users``user_groups`后,必须为这两个表创建 JPA 实体。 实体会将数据库表映射到 Java 对象,因此您可以使用实体对象中的 getter 和 setter 方法轻松地修改或获取数据库。 使用@Entity 注解将 Java 类标记为实体。 该类还必须实现 Serializable 接口。
这是**用户实体**的代码 这是**用户实体**的代码
...@@ -193,7 +193,7 @@ public class User implements Serializable { ...@@ -193,7 +193,7 @@ public class User implements Serializable {
在第 18 行,@ Id 注释用于将“电子邮件”表示为主字段 在第 18 行,@ Id 注释用于将“电子邮件”表示为主字段
@Column 批注用于将字段从 Java 类映射到表中的字段 @Column 注解用于将字段从 Java 类映射到表中的字段
**团体实体** **团体实体**
...@@ -360,7 +360,7 @@ public class UserEJB { ...@@ -360,7 +360,7 @@ public class UserEJB {
请注意,第 16 行的 Bean 被注释为@Stateless。 请注意,第 16 行的 Bean 被注释为@Stateless。
在第 19 行,EntityManager 指向“ tutorialsPU”作为持久性单元,全部通过@PersistenceContext 批注完成。 我们在`persistence.xml`文件中指定了持久性单元 在第 19 行,EntityManager 指向“ tutorialsPU”作为持久性单元,全部通过@PersistenceContext 注解完成。 我们在`persistence.xml`文件中指定了持久性单元
`createUser`方法首先将纯文本密码编码为 SHA-256 字符串,然后将两个对象(用户和组)存储到数据库中。 `createUser`方法首先将纯文本密码编码为 SHA-256 字符串,然后将两个对象(用户和组)存储到数据库中。
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
## 什么是 SPA? ## 什么是 SPA?
单页应用程序是一种设计模式,特别是一种确定程序流程的体系结构设计模式。 这样做的想法是一次加载所有数据和元素,以防止在用户使用页面时刷新页面。 例如,您可能已经注意到,首次加载 Gmail 后,它甚至可以脱机运行,而且运行速度也很快。 Gmail,Facebook,GitHub 和许多其他应用程序使用 SPA 来提供自然的 UX,以保持不受干扰的用法。 如今,这种想法已逐渐发展为一种设计方向,PWA 则采用了相同的概念,即提供几乎自然的离线体验。 单页应用程序是一种设计模式,特别是一种确定程序流程的构设计模式。 这样做的想法是一次加载所有数据和元素,以防止在用户使用页面时刷新页面。 例如,您可能已经注意到,首次加载 Gmail 后,它甚至可以脱机运行,而且运行速度也很快。 Gmail,Facebook,GitHub 和许多其他应用程序使用 SPA 来提供自然的 UX,以保持不受干扰的用法。 如今,这种想法已逐渐发展为一种设计方向,PWA 则采用了相同的概念,即提供几乎自然的离线体验。
![Traditional page lifecycle vs. SPA lifecycle](img/ded351ccbdd0cdcb8cf9826a38421aa4.jpg) ![Traditional page lifecycle vs. SPA lifecycle](img/ded351ccbdd0cdcb8cf9826a38421aa4.jpg)
...@@ -38,7 +38,7 @@ Java Enterprise Edition 是健壮的技术和 API 的分组集合,用于企业 ...@@ -38,7 +38,7 @@ Java Enterprise Edition 是健壮的技术和 API 的分组集合,用于企业
## 后端 ## 后端
Java Persistence API 将使我们能够管理和操纵应用程序和服务器之间的数据。 通过使用`@Entity`批注,我们可以将对象类建模为数据库内部的数据库实体。 您可能已经猜到`@ID`为此关系设置了主键,这是事实。 我们可以使用`@table`表示法来指定某些表属性,例如唯一性约束(数据成员必须是唯一的,即候选键)和表名。 `@namedqueries`允许我们准备某些查询以用于该关系。 然后,我们继续使用构造函数,setter 和 getter 构建基本类。 Java Persistence API 将使我们能够管理和操纵应用程序和服务器之间的数据。 通过使用`@Entity`注解,我们可以将对象类建模为数据库内部的数据库实体。 您可能已经猜到`@ID`为此关系设置了主键,这是事实。 我们可以使用`@table`表示法来指定某些表属性,例如唯一性约束(数据成员必须是唯一的,即候选键)和表名。 `@namedqueries`允许我们准备某些查询以用于该关系。 然后,我们继续使用构造函数,setter 和 getter 构建基本类。
![Actor Entity class](img/2d0c4fa1f3b3a5503b8970144d0f2d73.jpg) ![Actor Entity class](img/2d0c4fa1f3b3a5503b8970144d0f2d73.jpg)
......
...@@ -111,7 +111,7 @@ Spring WhiteLabel 错误页面 ...@@ -111,7 +111,7 @@ Spring WhiteLabel 错误页面
## 创建请求映射 ## 创建请求映射
现在,为了能够在 http:// localhost:8080 下看到一些``有意义的''内容,我们需要更改出价`SpringBootExampleApplication.java`的代码。 首先使用`@Controller`批注对类进行批注。 其次,创建一个映射到 URL“ /”的请求-这会将`home()`方法映射到该 URL。 换句话说,当浏览器向 http:// localhost:8080 发出 GET 请求时,将通过此方法提供服务。 最后,为了能够将响应返回给浏览器,您需要使用`@ResponseBody`注释`home()`方法。 您将在下面找到所有更改: 现在,为了能够在 http:// localhost:8080 下看到一些``有意义的''内容,我们需要更改出价`SpringBootExampleApplication.java`的代码。 首先使用`@Controller`注解对类进行注解。 其次,创建一个映射到 URL“ /”的请求-这会将`home()`方法映射到该 URL。 换句话说,当浏览器向 http:// localhost:8080 发出 GET 请求时,将通过此方法提供服务。 最后,为了能够将响应返回给浏览器,您需要使用`@ResponseBody`注释`home()`方法。 您将在下面找到所有更改:
```java ```java
package net.javavatutorial.tutorials; package net.javavatutorial.tutorials;
......
...@@ -16,9 +16,9 @@ ...@@ -16,9 +16,9 @@
当您要“声明”一个类作为控制器时,就像使用 @Controller 对其进行注释一样简单。 在类级别使用时,控制器现在可以处理 REST API 请求。 当您要“声明”一个类作为控制器时,就像使用 @Controller 对其进行注释一样简单。 在类级别使用时,控制器现在可以处理 REST API 请求。
### GetMapping 批注 ### GetMapping 注解
当使用 @Controller 批注时,可以通过使用该方法的 RequestMapping 批注来提供请求映射。 还有 @ RequestMapping,@ PostMapping,@ PutMapping 可以简化常见 HTTP 方法类型的映射。 当使用 @Controller 注解时,可以通过使用该方法的 RequestMapping 注解来提供请求映射。 还有 @ RequestMapping,@ PostMapping,@ PutMapping 可以简化常见 HTTP 方法类型的映射。
```java ```java
package com.example.demo; package com.example.demo;
...@@ -48,7 +48,7 @@ public class DemoApplication { ...@@ -48,7 +48,7 @@ public class DemoApplication {
上面的代码段,我们创建了一个 DemoApplication,其注释为@Controller 和@SpringBootApplication。 请注意 **@GetRequest(“ /”)**的使用。 这就是说 home()方法将显示注释中放置的内容,在本例中为“ /”,即 http:// localhost:8080 **/。** 上面的代码段,我们创建了一个 DemoApplication,其注释为@Controller 和@SpringBootApplication。 请注意 **@GetRequest(“ /”)**的使用。 这就是说 home()方法将显示注释中放置的内容,在本例中为“ /”,即 http:// localhost:8080 **/。**
在示例中,我使用的是 @RestConroller ,它基本上是控制器的专用版本,其中包括 @Controller 和@ ResponseBody 批注。 它只是简化了控制器的实现。 在示例中,我使用的是 @RestConroller ,它基本上是控制器的专用版本,其中包括 @Controller 和@ ResponseBody 注解。 它只是简化了控制器的实现。
当我们运行上面的代码时,我们得到以下结果: 当我们运行上面的代码时,我们得到以下结果:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
> 原文: [https://javatutorial.net/pathvariable-annotation-in-spring](https://javatutorial.net/pathvariable-annotation-in-spring) > 原文: [https://javatutorial.net/pathvariable-annotation-in-spring](https://javatutorial.net/pathvariable-annotation-in-spring)
就像@RequestParam 一样,@PathVariable 批注用于从 HTTP request 中提取数据。 但是,它们略有不同。 区别在于@RequestParam 从 URL 获取参数,而@PathVariable 只是从 URI 中提取参数。 就像@RequestParam 一样,@PathVariable 注解用于从 HTTP request 中提取数据。 但是,它们略有不同。 区别在于@RequestParam 从 URL 获取参数,而@PathVariable 只是从 URI 中提取参数。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
...@@ -43,7 +43,7 @@ public class EmployeeManager { ...@@ -43,7 +43,7 @@ public class EmployeeManager {
现在,Spring 查看 out id 参数,并将其与模板变量“ id”进行匹配。 现在,Spring 查看 out id 参数,并将其与模板变量“ id”进行匹配。
请记住,如果我的代码将“ id”(参数)命名为其他名称,则将无法使用。 但是,如果您不想为参数和模板变量使用相同的名称,则可以指定 PathVariable 批注的名称,如下所示: 请记住,如果我的代码将“ id”(参数)命名为其他名称,则将无法使用。 但是,如果您不想为参数和模板变量使用相同的名称,则可以指定 PathVariable 注解的名称,如下所示:
```java ```java
@Controller @Controller
...@@ -62,9 +62,9 @@ public class EmployeeManager { ...@@ -62,9 +62,9 @@ public class EmployeeManager {
因此,最终您有两个选择: 因此,最终您有两个选择:
1. 方法参数使用相同的名称 1. 方法参数使用相同的名称
2. 在@PathVariable 批注中指定模板变量的名称 2. 在@PathVariable 注解中指定模板变量的名称
### 多个@PathVariable 批注 ### 多个@PathVariable 注解
如果您可以有多个@PathVariable,该怎么办? 我们可以做到吗? 我们可以! 实际上,这与添加单个@PathVariable 非常相似。 如果您可以有多个@PathVariable,该怎么办? 我们可以做到吗? 我们可以! 实际上,这与添加单个@PathVariable 非常相似。
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
> 原文: [https://javatutorial.net/requestbody-annotation-in-spring](https://javatutorial.net/requestbody-annotation-in-spring) > 原文: [https://javatutorial.net/requestbody-annotation-in-spring](https://javatutorial.net/requestbody-annotation-in-spring)
@RequestBody 批注可用于处理 Web 请求。 @RequestBody 注解可用于处理 Web 请求。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
更具体地说,它用于将方法参数与请求的主体绑定,其工作方式是 HttpMessageConverter 根据请求内容的类型转换请求的主体。 更具体地说,它用于将方法参数与请求的主体绑定,其工作方式是 HttpMessageConverter 根据请求内容的类型转换请求的主体。
### ###
```java ```java
<modifier> <return-type> <method-name> (@RequestBody <type> <name>) { <modifier> <return-type> <method-name> (@RequestBody <type> <name>) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
> 原文: [https://javatutorial.net/requestparam-annotation-in-spring](https://javatutorial.net/requestparam-annotation-in-spring) > 原文: [https://javatutorial.net/requestparam-annotation-in-spring](https://javatutorial.net/requestparam-annotation-in-spring)
当我们想在控制器类中读取 Web 请求参数时,将使用 RequestParam 批注。 换句话说,前端正在向我们发送一些带有键的参数(例如,从填充的表单中)。 当我们想在控制器类中读取 Web 请求参数时,将使用 RequestParam 注解。 换句话说,前端正在向我们发送一些带有键的参数(例如,从填充的表单中)。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
您可能想知道.. IoC 容器如何接收执行上述操作的数据? 答案来自 3 个地方中的 1 个:XML 文件,Java 代码或 Java 批注 您可能想知道.. IoC 容器如何接收执行上述操作的数据? 答案来自 3 个地方中的 1 个:XML 文件,Java 代码或 Java 注解
IoC 容器是 Spring 中的一个框架,用于管理 POJO(普通的旧 Java 对象)的生命周期,并在需要时将其插入 Java 程序中。 IoC 容器是 Spring 中的一个框架,用于管理 POJO(普通的旧 Java 对象)的生命周期,并在需要时将其插入 Java 程序中。
......
...@@ -80,7 +80,7 @@ public class ControllerExampleJSP { ...@@ -80,7 +80,7 @@ public class ControllerExampleJSP {
## 用 ResponseBody 实现控制器 ## 用 ResponseBody 实现控制器
与前面的示例不同,此示例将返回由方法而不是 JSP 页面生成的 String。 我们唯一需要更改的就是将`@ResponseBody`批注添加到我们的控制器方法中 与前面的示例不同,此示例将返回由方法而不是 JSP 页面生成的 String。 我们唯一需要更改的就是将`@ResponseBody`注解添加到我们的控制器方法中
```java ```java
package net.javatutorial.tutorials; package net.javatutorial.tutorials;
...@@ -151,7 +151,7 @@ public class RestControllerExample { ...@@ -151,7 +151,7 @@ public class RestControllerExample {
## 在方法和类级别使用@RequestMapping 注释 ## 在方法和类级别使用@RequestMapping 注释
Spring 4.3 引入了诸如`@GetMapping``@PostMapping``@PutMapping`批注,以指定常见 HTTP 方法类型(如 GET,POST 和 PUT)的映射。 这些注释增强了代码的可读性。 Spring 4.3 引入了诸如`@GetMapping``@PostMapping``@PutMapping`注解,以指定常见 HTTP 方法类型(如 GET,POST 和 PUT)的映射。 这些注释增强了代码的可读性。
以下示例演示了如何在方法和类级别上使用映射注释。 以下示例演示了如何在方法和类级别上使用映射注释。
......
...@@ -140,9 +140,9 @@ public class EmployeeDAOTest { ...@@ -140,9 +140,9 @@ public class EmployeeDAOTest {
在上一课中有两件事需要分解。 在上一课中有两件事需要分解。
首先,请注意,我们使用的@MockBean 批注只是将模拟对象添加到应用程序上下文中。 这意味着它将替换任何现有的相同类型的 bean。 如果没有现有的 bean,将创建一个新的 bean。 首先,请注意,我们使用的@MockBean 注解只是将模拟对象添加到应用程序上下文中。 这意味着它将替换任何现有的相同类型的 bean。 如果没有现有的 bean,将创建一个新的 bean。
然后,我们使用@BeforeEach 批注,该批注将在所有单元测试运行之前执行。 因此,该方法的名称为 **prepare,**,我们正在为单元测试准备“环境”。 然后,我们使用@BeforeEach 注解,该注解将在所有单元测试运行之前执行。 因此,该方法的名称为 **prepare,**,我们正在为单元测试准备“环境”。
在 prepare 方法中,我们有两件事。 由于 [SessionFactory](https://docs.spring.io/spring-integration/api/org/springframework/integration/file/remote/session/SessionFactory.html) 是一个功能接口,因此可以将其用作 lambda 表达式的分配。 在 prepare 方法中,我们有两件事。 由于 [SessionFactory](https://docs.spring.io/spring-integration/api/org/springframework/integration/file/remote/session/SessionFactory.html) 是一个功能接口,因此可以将其用作 lambda 表达式的分配。
......
...@@ -118,11 +118,11 @@ public class EmployeeAccountControllerTest { ...@@ -118,11 +118,11 @@ public class EmployeeAccountControllerTest {
* @BeforeEach:在每次单元测试之前运行的代码 * @BeforeEach:在每次单元测试之前运行的代码
* @Test:单元测试本身 * @Test:单元测试本身
* @DisplayName:JUnit5 批注,用于为单元测试分配描述性文本 * @DisplayName:JUnit5 注解,用于为单元测试分配描述性文本
* @Tag:可用于测试发现和执行 * @Tag:可用于测试发现和执行
* @ExtendWith(.class):将 Spring 5 Test 上下文框架与 JUnit 5 集成 * @ExtendWith(.class):将 Spring 5 Test 上下文框架与 JUnit 5 集成
因此,在上面的代码中,首先我们使用@ExtendWith 批注,该批注用于将 Spring 5 Test 框架与 JUnit 5 集成在一起。然后,我们使用@Tag 批注,用于指定这是 Test 类。 然后,我们再次使用@Mockbean 批注,它可以帮助我们模拟依赖项。 然后我们使用@BeforeEach 批注,该批注表示将在每个单元测试之前在 之前运行的代码 **。 在我们的案例中,建立员工服务。 然后,我们使用@Test 批注指定以下方法为 Test,然后我们也使用@DisplayName 批注,如上所述,该批注为单元测试方法提供了描述性文本(在代码段中不是最具描述性的) 但可以)。** 因此,在上面的代码中,首先我们使用@ExtendWith 注解,该注解用于将 Spring 5 Test 框架与 JUnit 5 集成在一起。然后,我们使用@Tag 注解,用于指定这是 Test 类。 然后,我们再次使用@Mockbean 注解,它可以帮助我们模拟依赖项。 然后我们使用@BeforeEach 注解,该注解表示将在每个单元测试之前在 之前运行的代码 **。 在我们的案例中,建立员工服务。 然后,我们使用@Test 注解指定以下方法为 Test,然后我们也使用@DisplayName 注解,如上所述,该注解为单元测试方法提供了描述性文本(在代码段中不是最具描述性的) 但可以)。**
在该方法中,我们将 Employee 实例转换为 JSON,然后将 Mock 行为设置为每次调用 validate()时都返回 **null** 。 然后我们调用控制器方法。 在该方法中,我们将 Employee 实例转换为 JSON,然后将 Mock 行为设置为每次调用 validate()时都返回 **null** 。 然后我们调用控制器方法。
......
...@@ -84,7 +84,7 @@ public class EmployeeController { ...@@ -84,7 +84,7 @@ public class EmployeeController {
} }
``` ```
因此现在我们将@RequestMapping 批注更改为 **@RequestMapping(“ / employee”,method = RequestMethod.GET)。** 正如我在本教程开始时所说的,我们还指定了我们希望结果为 JSON 格式。 因此我们可以将 **@RequestMapping(“ / employee”,method = RequestMethod.GET)更改为 **@RequestMapping(“ / employee”,method = RequestMethod.GET,Produces =“ application / json”) 。**** 因此现在我们将@RequestMapping 注解更改为 **@RequestMapping(“ / employee”,method = RequestMethod.GET)。** 正如我在本教程开始时所说的,我们还指定了我们希望结果为 JSON 格式。 因此我们可以将 **@RequestMapping(“ / employee”,method = RequestMethod.GET)更改为 **@RequestMapping(“ / employee”,method = RequestMethod.GET,Produces =“ application / json”) 。****
我们将查询参数“ id”提取到“ employeeId”,将“ firstName”提取到“ fName”,将“ lastName”提取到“ lName”,然后实例化一个**新的** Employee 对象并首先传递该 ID。 我们作为查询参数得到的名字和姓氏。 我们将查询参数“ id”提取到“ employeeId”,将“ firstName”提取到“ fName”,将“ lastName”提取到“ lName”,然后实例化一个**新的** Employee 对象并首先传递该 ID。 我们作为查询参数得到的名字和姓氏。
......
...@@ -70,7 +70,7 @@ public class AppConfiguration extends WebSecurityConfigurerAdapter { ...@@ -70,7 +70,7 @@ public class AppConfiguration extends WebSecurityConfigurerAdapter {
@ EnableOAuth2Sso 注释通知 Spring 配置 [OAuth2TokenRelayFilter](https://github.com/spring-cloud/spring-cloud-security/blob/master/spring-cloud-security/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java) 。 此过滤器从用户的 HTTP 会话中检索已获取的访问令牌,并填充它们。 @ EnableOAuth2Sso 注释通知 Spring 配置 [OAuth2TokenRelayFilter](https://github.com/spring-cloud/spring-cloud-security/blob/master/spring-cloud-security/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java) 。 此过滤器从用户的 HTTP 会话中检索已获取的访问令牌,并填充它们。
@Order 批注的工作是确保由我们的 WebSecurityConfigurerAdapter 创建的过滤器优先于由另一个 WebSecurityConfigurerAdapter 创建的过滤器。 @Order 注解的工作是确保由我们的 WebSecurityConfigurerAdapter 创建的过滤器优先于由另一个 WebSecurityConfigurerAdapter 创建的过滤器。
## @EnableResourceServer ## @EnableResourceServer
......
...@@ -110,7 +110,7 @@ public class DemoController { ...@@ -110,7 +110,7 @@ public class DemoController {
} }
``` ```
对于此控制器类,我们使用@RestController 批注,如果您不熟悉该批注,则它基本上可以供 Spring MVC 使用,以能够处理 Web 请求。 因此,所有到“ /”路径的 Web 请求都将由我们的 **handle()**方法处理。 将针对此特定路径(“ /”)处理 Web 请求的原因是因为我们使用@RequestMapping 批注将其映射到此 Web 路径。 对于此控制器类,我们使用@RestController 注解,如果您不熟悉该注解,则它基本上可以供 Spring MVC 使用,以能够处理 Web 请求。 因此,所有到“ /”路径的 Web 请求都将由我们的 **handle()**方法处理。 将针对此特定路径(“ /”)处理 Web 请求的原因是因为我们使用@RequestMapping 注解将其映射到此 Web 路径。
现在是时候创建我们的 Application 类了。 现在是时候创建我们的 Application 类了。
...@@ -139,9 +139,9 @@ public class Application { ...@@ -139,9 +139,9 @@ public class Application {
} }
``` ```
感谢@SpringBootApplication 批注,我们正在初始化 Spring Boot Application 的入口点。 请注意,我们在此类中有 main 方法。 感谢@SpringBootApplication 注解,我们正在初始化 Spring Boot Application 的入口点。 请注意,我们在此类中有 main 方法。
@SpringBootApplication 批注包含@ EnableAutoConfiguration,@ ComponentScan 和@SpringBootConfiguration。 使用@SpringBootApplication 批注时,我们“调用”了所有上述批注 @SpringBootApplication 注解包含@ EnableAutoConfiguration,@ ComponentScan 和@SpringBootConfiguration。 使用@SpringBootApplication 注解时,我们“调用”了所有上述注解
## 运行应用程序 ## 运行应用程序
......
...@@ -44,7 +44,7 @@ _ 强大–_ MVC 架构支持异步技术,这意味着使用此模式构建的 ...@@ -44,7 +44,7 @@ _ 强大–_ MVC 架构支持异步技术,这意味着使用此模式构建的
## 如何定义一个控制器? ## 如何定义一个控制器?
@Controller 注释用于使类的行为类似于 Controller。 我们还可以在@Controller 旁边使用@RequestMapping 批注,以指定类或方法的 URL 路由。 在我们的例子中,我们将为整个 Controller 类指定 URL。 @Controller 注释用于使类的行为类似于 Controller。 我们还可以在@Controller 旁边使用@RequestMapping 注解,以指定类或方法的 URL 路由。 在我们的例子中,我们将为整个 Controller 类指定 URL。
```java ```java
@Controller @Controller
...@@ -64,7 +64,7 @@ public class ControllerDemo { ...@@ -64,7 +64,7 @@ public class ControllerDemo {
## 如何创建视图? ## 如何创建视图?
上面,我提到了灵活性是该体系结构的优势之一。 好吧,Spring MVC 支持多种视图技术– HTML,PDF,Excel,XML 等。 因此,您的技术将得到支持。 这给您灵活性(无双关语),可以选择您最喜欢使用的任何技术。 上面,我提到了灵活性是该构的优势之一。 好吧,Spring MVC 支持多种视图技术– HTML,PDF,Excel,XML 等。 因此,您的技术将得到支持。 这给您灵活性(无双关语),可以选择您最喜欢使用的任何技术。
就我们而言,我们将使用 HTML 创建视图。 就我们而言,我们将使用 HTML 创建视图。
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
> 原文: [https://javatutorial.net/autowired-annotation-in-spring](https://javatutorial.net/autowired-annotation-in-spring) > 原文: [https://javatutorial.net/autowired-annotation-in-spring](https://javatutorial.net/autowired-annotation-in-spring)
@Autowired 批注是实现依赖注入的一种相对较新的样式。 它允许您将其他豆注入另一个所需的豆中。 与@ 必需的批注类似,@ Autowired 批注可用于在 setter 方法以及构造函数和属性上“自动装配” bean。 @Autowired 注解是实现依赖注入的一种相对较新的样式。 它允许您将其他豆注入另一个所需的豆中。 与@ 必需的注解类似,@ Autowired 注解可用于在 setter 方法以及构造函数和属性上“自动装配” bean。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
## @Setter 方法上的自动标注 ## @Setter 方法上的自动标注
请注意,在 setter 方法上使用@Autowired 批注时,它会自动摆脱 XML 配置文件中的 &lt;属性&gt; 元素。 相反,当 Spring 发现使用@Autowired 注释的 setter 方法时,它将对该特定方法执行 **byType** “自动装配”。 请注意,在 setter 方法上使用@Autowired 注解时,它会自动摆脱 XML 配置文件中的 &lt;属性&gt; 元素。 相反,当 Spring 发现使用@Autowired 注释的 setter 方法时,它将对该特定方法执行 **byType** “自动装配”。
让我们看看@Autowired 在实践中。 更具体地说,在设置方法上使用@Autowired。 让我们看看@Autowired 在实践中。 更具体地说,在设置方法上使用@Autowired。
...@@ -30,7 +30,7 @@ public class ExampleService { ...@@ -30,7 +30,7 @@ public class ExampleService {
上面的示例中没有什么花哨的。 我们只有一个名为 **ExampleService** 的服务类,该类具有一个 **Employee** 类型的实例变量,并且有一个名为 **setEmployee(Employee emp)**的设置方法,该方法仅用于设置雇员 作为论证给出的任何东西。 上面的示例中没有什么花哨的。 我们只有一个名为 **ExampleService** 的服务类,该类具有一个 **Employee** 类型的实例变量,并且有一个名为 **setEmployee(Employee emp)**的设置方法,该方法仅用于设置雇员 作为论证给出的任何东西。
感谢@Autowired 批注,在实例化 ExampleService 时,将 Employee 的实例作为该方法的参数注入。 感谢@Autowired 注解,在实例化 ExampleService 时,将 Employee 的实例作为该方法的参数注入。
## 构造函数上的@Autowired 注释 ## 构造函数上的@Autowired 注释
...@@ -55,7 +55,7 @@ public class ExampleService { ...@@ -55,7 +55,7 @@ public class ExampleService {
## 属性上的@Autowired 注释 ## 属性上的@Autowired 注释
自动装配属性节省了我们的时间和代码行。 怎么样? 好吧,当我们在属性上使用该批注时,这些属性不再需要 getter 和 setter。 酷吧? 自动装配属性节省了我们的时间和代码行。 怎么样? 好吧,当我们在属性上使用该注解时,这些属性不再需要 getter 和 setter。 酷吧?
```java ```java
public class ExampleService { public class ExampleService {
...@@ -105,4 +105,4 @@ public class ExampleService { ...@@ -105,4 +105,4 @@ public class ExampleService {
## 总结 ## 总结
通过使用@Autowired 批注,我们节省了几行代码,还节省了一些时间,因为我们不需要指定属性和构造函数参数。 通过使用@Autowired 注解,我们节省了几行代码,还节省了一些时间,因为我们不需要指定属性和构造函数参数。
\ No newline at end of file \ No newline at end of file
...@@ -46,9 +46,9 @@ public class Example { ...@@ -46,9 +46,9 @@ public class Example {
### AOP 咨询类型 ### AOP 咨询类型
1. 在建议之前:这些建议在执行连接点方法之前运行。 要将建议类型标记为之前,我们可以使用@Before 注释。 1. 在建议之前:这些建议在执行连接点方法之前运行。 要将建议类型标记为之前,我们可以使用@Before 注释。
2. 忠告之后:这些忠告在执行连接点方法之后运行。 要将建议类型标记为 After,可以使用@After 批注 2. 忠告之后:这些忠告在执行连接点方法之后运行。 要将建议类型标记为 After,可以使用@After 注解
3. 返回建议之后:仅在连接点方法正常执行(不表示异常)时运行这些建议。 要将建议类型标记为“返回后”,我们可以使用@AfterReturning 批注 3. 返回建议之后:仅在连接点方法正常执行(不表示异常)时运行这些建议。 要将建议类型标记为“返回后”,我们可以使用@AfterReturning 注解
4. 抛出建议后:仅在连接点方法抛出异常时才运行这些建议(与“返回建议之后”相反)。 要将建议类型标记为“抛后”,我们可以使用@AfterThrowing 批注 4. 抛出建议后:仅在连接点方法抛出异常时才运行这些建议(与“返回建议之后”相反)。 要将建议类型标记为“抛后”,我们可以使用@AfterThrowing 注解
5. 围绕建议:这些建议为我们提供了灵活性,因为借助它们的使用,我们可以选择是否执行连接点方法。 5. 围绕建议:这些建议为我们提供了灵活性,因为借助它们的使用,我们可以选择是否执行连接点方法。
让我们看看如何实现这些不同的建议类型。 让我们看看如何实现这些不同的建议类型。
...@@ -68,7 +68,7 @@ public class BeforeAdviceDemo { ...@@ -68,7 +68,7 @@ public class BeforeAdviceDemo {
} }
``` ```
通过使用@Before 批注,我们指定这是一个 **BeforeAdvice。** 通过使用@Before 注解,我们指定这是一个 **BeforeAdvice。**
**咨询后** **咨询后**
......
...@@ -17,7 +17,7 @@ bean 的定义包含称为**配置元数据的内容。** 容器需要知道如 ...@@ -17,7 +17,7 @@ bean 的定义包含称为**配置元数据的内容。** 容器需要知道如
## 如何声明一个 Bean? ## 如何声明一个 Bean?
我们可以简单地通过使用@Bean 批注来声明一个 bean。 声明带有@Bean 批注的方法的示例: 我们可以简单地通过使用@Bean 注解来声明一个 bean。 声明带有@Bean 注解的方法的示例:
```java ```java
@Configuration @Configuration
......
...@@ -10,13 +10,13 @@ Activity 是 Android 应用程序开发的基本组成部分之一。 就像带 ...@@ -10,13 +10,13 @@ Activity 是 Android 应用程序开发的基本组成部分之一。 就像带
## 活动生命周期 ## 活动生命周期
在 Android 应用程序中,Android 活动具有其自身的生命周期。 活动存储和管理在称为活动堆栈的堆栈中。 新活动位于堆栈顶部并开始运行,而以前的活动则位于堆栈中新活动的下方。 当堆栈中的顶部活动退出时,从下至上的活动将变为活动状态。 在 Android 应用程序中,Android 活动具有其自身的生命周期。 活动存储和管理在称为活动栈的栈中。 新活动位于栈顶部并开始运行,而以前的活动则位于栈中新活动的下方。 当栈中的顶部活动退出时,从下至上的活动将变为活动状态。
### **Android 活动状态** ### **Android 活动状态**
一个活动有四个状态 一个活动有四个状态
**正在运行:**栈顶部的活动处于运行或活动状态,表示该活动位于屏幕的前台。 **正在运行:**栈顶部的活动处于运行或活动状态,表示该活动位于屏幕的前台。
**已暂停:**处于活动状态但未专注的活动处于暂停状态。 (这是活动中显示的弹出消息)。 **已暂停:**处于活动状态但未专注的活动处于暂停状态。 (这是活动中显示的弹出消息)。
......
...@@ -142,7 +142,7 @@ public class CustomLanguageComponent extends ResourceBundle { ...@@ -142,7 +142,7 @@ public class CustomLanguageComponent extends ResourceBundle {
} }
``` ```
可以看出,我们正在创建扩展了`ResourceBundle`的自定义类`CustomLanguageComponent`,并在@Component 批注中指定了属性= {“ language.id = en_US”}。 我们指出要覆盖`Language_en.properties`文件。 可以看出,我们正在创建扩展了`ResourceBundle`的自定义类`CustomLanguageComponent`,并在@Component 注解中指定了属性= {“ language.id = en_US”}。 我们指出要覆盖`Language_en.properties`文件。
现在,在`/language-fragmentmodule/src/main/resources/content`下创建`Language_en.properties`,并使用我们的自定义消息添加身份验证失败的属性。 现在,在`/language-fragmentmodule/src/main/resources/content`下创建`Language_en.properties`,并使用我们的自定义消息添加身份验证失败的属性。
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
> 原文: [https://javatutorial.net/jvm-explained](https://javatutorial.net/jvm-explained) > 原文: [https://javatutorial.net/jvm-explained](https://javatutorial.net/jvm-explained)
本文介绍了 Java 虚拟机(JVM)及其体系结 本文介绍了 Java 虚拟机(JVM)及其
JVM 代表 Java 虚拟机。 它为您提供了执行已编译程序的环境,称为字节码。 来自不同供应商的 JVM 有多种实现,可用于各种平台。 在本文中,我将解释 JVM 的主要组件,包括内存管理,类加载和垃圾收集器。 JVM 代表 Java 虚拟机。 它为您提供了执行已编译程序的环境,称为字节码。 来自不同供应商的 JVM 有多种实现,可用于各种平台。 在本文中,我将解释 JVM 的主要组件,包括内存管理,类加载和垃圾收集器。
...@@ -80,10 +80,10 @@ JVM 要求维护以下所有属性: ...@@ -80,10 +80,10 @@ JVM 要求维护以下所有属性:
#### 栈区 #### 栈区
对于每个线程,将创建一个单独的运行时堆栈。 对于每个方法调用,将在堆栈存储器中创建一个条目,称为堆栈帧。 所有局部变量都将在堆栈存储器中创建。 堆栈区域是线程安全的,因为它不是共享资源。 堆栈框架分为三个子实体: 对于每个线程,将创建一个单独的运行时栈。 对于每个方法调用,将在栈存储器中创建一个条目,称为栈帧。 所有局部变量都将在栈存储器中创建。 栈区域是线程安全的,因为它不是共享资源。 栈框架分为三个子实体:
* 局部变量数组–与该方法有关,涉及多少局部变量,并且相应的值将存储在此处。 * 局部变量数组–与该方法有关,涉及多少局部变量,并且相应的值将存储在此处。
* 操作数堆栈–如果需要执行任何中间操作,则操作数堆栈充当执行该操作的运行时工作区。 * 操作数栈–如果需要执行任何中间操作,则操作数栈充当执行该操作的运行时工作区。
* 帧数据–与该方法相对应的所有符号都存储在此处。 在任何例外情况下,捕获块信息都将保留在帧数据中。 * 帧数据–与该方法相对应的所有符号都存储在此处。 在任何例外情况下,捕获块信息都将保留在帧数据中。
#### PC 寄存器 #### PC 寄存器
...@@ -92,7 +92,7 @@ JVM 要求维护以下所有属性: ...@@ -92,7 +92,7 @@ JVM 要求维护以下所有属性:
#### 本机方法栈 #### 本机方法栈
本机方法堆栈保存本机方法信息。 对于每个线程,将创建一个单独的本机方法堆栈。 本机方法栈保存本机方法信息。 对于每个线程,将创建一个单独的本机方法栈。
### 执行引擎 ### 执行引擎
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
> 原文: [https://javatutorial.net/java-memory-examples](https://javatutorial.net/java-memory-examples) > 原文: [https://javatutorial.net/java-memory-examples](https://javatutorial.net/java-memory-examples)
内存可以描述为字节数组,您可以在其中单独访问每个字节。 就像在 Java 中的[数组](https://javatutorial.net/java-array)中一样,在内存中的每个字节或更确切的位置上,都有可以访问的数据。 在 32 位体系结构中,每个内存“插槽”包含 32 位,也称为 1 个字,或仅 4 个字节。 内存可以描述为字节数组,您可以在其中单独访问每个字节。 就像在 Java 中的[数组](https://javatutorial.net/java-array)中一样,在内存中的每个字节或更确切的位置上,都有可以访问的数据。 在 32 位构中,每个内存“插槽”包含 32 位,也称为 1 个字,或仅 4 个字节。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
在上面的表示中,4000、4004、4008 等表示内存插槽的地址,或者在与数组,数据的索引或内存位置进行的比较中。 这些“随机值”中的每一个代表 32 位。 由于每个内存插槽占用 32 位或 4 个字节,因此内存地址每次增加 4。 在上面的表示中,4000、4004、4008 等表示内存插槽的地址,或者在与数组,数据的索引或内存位置进行的比较中。 这些“随机值”中的每一个代表 32 位。 由于每个内存插槽占用 32 位或 4 个字节,因此内存地址每次增加 4。
通常,在 Java 和一般的编程中,有两种类型的可变范围– **全局****局部**。 全局变量是可以从程序中的任何地方访问的变量,而局部变量是只能在给定函数中创建它们的地方访问的变量。 因此,这两种不同类型的变量作用域存储在不同的存储区域中-**栈****数据。** 通常,在 Java 和一般的编程中,有两种类型的可变范围– **全局****局部**。 全局变量是可以从程序中的任何地方访问的变量,而局部变量是只能在给定函数中创建它们的地方访问的变量。 因此,这两种不同类型的变量作用域存储在不同的存储区域中-**栈****数据。**
![Memory regions](img/3977ced81858595e9eccbc2660b4817d.jpg) ![Memory regions](img/3977ced81858595e9eccbc2660b4817d.jpg)
...@@ -27,7 +27,7 @@ public void doSomething() { ...@@ -27,7 +27,7 @@ public void doSomething() {
} }
``` ```
在上面的简单 Java 示例中, v 存储在栈存储区域中。 这是因为 v 是局部变量。 在上面的简单 Java 示例中, v 存储在栈存储区域中。 这是因为 v 是局部变量。
## 静态数据 ## 静态数据
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
> 原文: [https://javatutorial.net/java-parallel-streams-example](https://javatutorial.net/java-parallel-streams-example) > 原文: [https://javatutorial.net/java-parallel-streams-example](https://javatutorial.net/java-parallel-streams-example)
通过流 API,开发人员可以通过创建并行流并提高程序执行操作的速度来利用多核体系结构并提高 Java 程序的性能。 通过流 API,开发人员可以通过创建并行流并提高程序执行操作的速度来利用多核构并提高 Java 程序的性能。
![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg) ![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
## 什么是 Eclipse IDE ## 什么是 Eclipse IDE
IDE 代表集成开发环境。 换句话说,Eclipse 是功能强大且高级的文本编辑器,具有许多插件和工具。 使用 Eclipse,您可以更快地编写 Java 程序并按一下按钮即可执行它们。 但是 Eclipse 的功能更多。 插件体系结构使您能够不断添加所需的开发工具。 IDE 代表集成开发环境。 换句话说,Eclipse 是功能强大且高级的文本编辑器,具有许多插件和工具。 使用 Eclipse,您可以更快地编写 Java 程序并按一下按钮即可执行它们。 但是 Eclipse 的功能更多。 插件构使您能够不断添加所需的开发工具。
您始终可以以“老式方式”编译和运行程序。 有关更多详细信息,请阅读我们以前的教程[简单 Java 示例](https://javatutorial.net/simple-java-example "Simple Java Example")。 但是,如果您想像专业人士一样编码,则必须学习如何使用行业标准 IDE(例如 Eclipse)。 您始终可以以“老式方式”编译和运行程序。 有关更多详细信息,请阅读我们以前的教程[简单 Java 示例](https://javatutorial.net/simple-java-example "Simple Java Example")。 但是,如果您想像专业人士一样编码,则必须学习如何使用行业标准 IDE(例如 Eclipse)。
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
## 什么是`JFrame`? ## 什么是`JFrame`?
JFrame 是 java.awt.frame 扩展的 javax.swing 包类,它增加了对 JFC / SWING 组件体系结构的支持。 这是顶层窗口,带有边框和标题栏。 JFrame 类具有许多可用于自定义它的方法。 JFrame 是 java.awt.frame 扩展的 javax.swing 包类,它增加了对 JFC / SWING 组件构的支持。 这是顶层窗口,带有边框和标题栏。 JFrame 类具有许多可用于自定义它的方法。
## 创建一个`JFrame` ## 创建一个`JFrame`
......
...@@ -12,7 +12,7 @@ Java 中的 LinkedList 类使用双链表来存储元素,并且还提供了链 ...@@ -12,7 +12,7 @@ Java 中的 LinkedList 类使用双链表来存储元素,并且还提供了链
* Java 中的 LinkedList 类维护插入顺序。 * Java 中的 LinkedList 类维护插入顺序。
* Java 中的 LinkedList 类是不同步的。 * Java 中的 LinkedList 类是不同步的。
* Java 中的 LinkedList 类允许快速操作,因为不需要进行任何移位。 * Java 中的 LinkedList 类允许快速操作,因为不需要进行任何移位。
* Java 中的 LinkedList 类可以是列表,栈甚至队列。 * Java 中的 LinkedList 类可以是列表,栈甚至队列。
## `LinkedList`的局限性 ## `LinkedList`的局限性
...@@ -44,8 +44,8 @@ Java 中的 LinkedList ...@@ -44,8 +44,8 @@ Java 中的 LinkedList
8. E get(int index):返回列表中指定位置的元素。 8. E get(int index):返回列表中指定位置的元素。
9. int indexOf(Object o)返回列表中指定元素首次出现的索引,如果不存在则返回-1。 9. int indexOf(Object o)返回列表中指定元素首次出现的索引,如果不存在则返回-1。
10. boolean offer(E e):将指定的元素添加为列表的最后一个元素。 10. boolean offer(E e):将指定的元素添加为列表的最后一个元素。
11. E pop():从列表表示的栈中弹出一个元素。 11. E pop():从列表表示的栈中弹出一个元素。
12. void push(E e):将元素压入列表表示的栈。 12. void push(E e):将元素压入列表表示的栈。
13. E remove():用于检索和删除列表的第一个元素。 13. E remove():用于检索和删除列表的第一个元素。
14. E remove(int index):删除列表中指定位置的元素。 14. E remove(int index):删除列表中指定位置的元素。
15. int size():返回列表中的元素数。 15. int size():返回列表中的元素数。
......
...@@ -75,7 +75,7 @@ TreeSet: [Elephant, Tiger, Lion] ...@@ -75,7 +75,7 @@ TreeSet: [Elephant, Tiger, Lion]
### 使用`first()`和`last()`获取`TreeSet`的第一个和最后一个元素 ### 使用`first()`和`last()`获取`TreeSet`的第一个和最后一个元素
法: 法:
treeSet.first() treeSet.first()
...@@ -242,7 +242,7 @@ Empty: true ...@@ -242,7 +242,7 @@ Empty: true
## 使用`Iterator()`遍历树集 ## 使用`Iterator()`遍历树集
法: 法:
```java ```java
Iterator iterator = ts.iterator(); Iterator iterator = ts.iterator();
...@@ -285,7 +285,7 @@ Lion ...@@ -285,7 +285,7 @@ Lion
## 使用增强的`for`循环遍历树集 ## 使用增强的`for`循环遍历树集
法: 法:
```java ```java
for (String animal : animals) for (String animal : animals)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
BFS 使用与深度优先搜索完全相反的工作流程,反之亦然。 BFS 使用与深度优先搜索完全相反的工作流程,反之亦然。
在 BFS 和 DFS 之间的实现方面,一个很大的不同是 BFS 使用队列,而 DFS 使用栈。 在 BFS 和 DFS 之间的实现方面,一个很大的不同是 BFS 使用队列,而 DFS 使用栈。
![Workflow of BFS](img/5f2c7003f89c79609c5f829408b709f4.jpg) ![Workflow of BFS](img/5f2c7003f89c79609c5f829408b709f4.jpg)
......
...@@ -57,13 +57,13 @@ ...@@ -57,13 +57,13 @@
大欧米茄,也称为下界,用Ω符号表示。 大欧米茄,也称为下界,用Ω符号表示。
## 大(O) ## 大 O
如果执行时间与输入大小的对数成正比,则可以说该算法以对数时间运行。 例如,如果 Java 中有一个数组,其中包含 5 个苹果,并且您需要打印每个苹果,则该数组将为 O(5)或换句话说,为 O(数组的长度)或 O(n)。 如果执行时间与输入大小的对数成正比,则可以说该算法以对数时间运行。 例如,如果 Java 中有一个数组,其中包含 5 个苹果,并且您需要打印每个苹果,则该数组将为 O(5)或换句话说,为 O(数组的长度)或 O(n)。
这种时间复杂度的算法的一个著名示例是 Binary Search。 这种时间复杂度的算法的一个著名示例是 Binary Search。
## 大西塔 ## 大 Θ
如果 T(n)是Θ(f(n)),则意味着 T(n)增长(精确)与 f(n)一样快。 n + n 仍然是 n。 是不是有点满嘴? 让我们尝试一个更简单的解释。 如果 T(n)是Θ(f(n)),则意味着 T(n)增长(精确)与 f(n)一样快。 n + n 仍然是 n。 是不是有点满嘴? 让我们尝试一个更简单的解释。
......
...@@ -21,7 +21,7 @@ Java 中有 4 种引用类型: ...@@ -21,7 +21,7 @@ Java 中有 4 种引用类型:
弱引用需要显式声明,因为默认情况下,Java 将引用标记为强引用。 弱引用需要显式声明,因为默认情况下,Java 将引用标记为强引用。
## 什么是较弱的可达性? ## 什么是可达性?
这意味着一个对象既没有强引用也没有软引用指向它,并且只能通过遍历弱引用来访问。 这意味着一个对象既没有强引用也没有软引用指向它,并且只能通过遍历弱引用来访问。
......
# 基本 Java 正则表达式 # Java 基本正则表达式
> 原文: [https://javatutorial.net/basic-java-regular-expressions](https://javatutorial.net/basic-java-regular-expressions) > 原文: [https://javatutorial.net/basic-java-regular-expressions](https://javatutorial.net/basic-java-regular-expressions)
...@@ -75,7 +75,7 @@ it's ...@@ -75,7 +75,7 @@ it's
me me
``` ```
## 级联 ## 连接
使用正则表达式,我们可以连续匹配一个字符串或多个字符,并以此作为正则表达式模式。 例如,模式“ ing”将匹配如下: 使用正则表达式,我们可以连续匹配一个字符串或多个字符,并以此作为正则表达式模式。 例如,模式“ ing”将匹配如下:
...@@ -83,7 +83,7 @@ me ...@@ -83,7 +83,7 @@ me
换句话说,如果在我们的字符串中提供“ ing”,则该字符串匹配。 换句话说,如果在我们的字符串中提供“ ing”,则该字符串匹配。
## 结合串联和重复 ## 结合连接和重复
模式:“ ar +”将匹配 模式:“ ar +”将匹配
...@@ -97,7 +97,7 @@ me ...@@ -97,7 +97,7 @@ me
*(星号)将匹配“ i”,后跟零个或多个“ t”。 在我们的示例中,它将匹配“ it”,“ itt”,“ i”,“ i” *(星号)将匹配“ i”,后跟零个或多个“ t”。 在我们的示例中,它将匹配“ it”,“ itt”,“ i”,“ i”
## 轮换 ## 交替
模式:“ ea | in”将匹配 模式:“ ea | in”将匹配
...@@ -105,7 +105,7 @@ me ...@@ -105,7 +105,7 @@ me
| (竖线符号)将匹配“ ea”或“ in”。 | (竖线符号)将匹配“ ea”或“ in”。
## 角色 ## 字符
模式:“ [123]”将匹配 模式:“ [123]”将匹配
...@@ -113,7 +113,7 @@ me ...@@ -113,7 +113,7 @@ me
[]匹配集合中的任何字符 []匹配集合中的任何字符
## 比赛范围 ## 匹配范围
模式:“ [1-3]”将匹配 模式:“ [1-3]”将匹配
...@@ -125,7 +125,7 @@ me ...@@ -125,7 +125,7 @@ me
## 排除字符 ## 排除字符
模式:“ [^ a-z123́]”将匹配 模式:“ [^ a-z123]”将匹配
“ E 赚钱很容易,因为计算 1 2 33 。 N 啊! “ E 赚钱很容易,因为计算 1 2 33 。 N 啊!
......
...@@ -6,11 +6,11 @@ Java 内存模型指定 [Java 虚拟机](https://javatutorial.net/jvm-explained) ...@@ -6,11 +6,11 @@ Java 内存模型指定 [Java 虚拟机](https://javatutorial.net/jvm-explained)
## Java 内存模型 ## Java 内存模型
[JVM](https://javatutorial.net/jvm-explained) 内部使用的 Java 内存模型在线程堆栈和堆之间分配内存。 JVM 中运行的每个线程都有自己的线程堆栈。 **线程堆栈**包含有关线程调用了哪些方法以达到当前执行点的信息。 它还包含每个正在执行的方法的所有局部变量。 [JVM](https://javatutorial.net/jvm-explained) 内部使用的 Java 内存模型在线程栈和堆之间分配内存。 JVM 中运行的每个线程都有自己的线程栈。 **线程栈**包含有关线程调用了哪些方法以达到当前执行点的信息。 它还包含每个正在执行的方法的所有局部变量。
![java memmory model](img/1d4849ebded3229c72686e16ad468998.jpg) ![java memmory model](img/1d4849ebded3229c72686e16ad468998.jpg)
基本类型的所有局部变量(`boolean``byte``short``char``int``long``float``double`)都完全存储在线程栈中,因此没有 对其他线程可见。 基本类型的所有局部变量(`boolean``byte``short``char``int``long``float``double`)都完全存储在线程栈中,因此没有 对其他线程可见。
**堆**包含 Java 应用程序中创建的所有对象,而不管创建该对象的线程如何。 这包括原始类型的对象版本(例如`Byte``Integer``Long`等)。 **堆**包含 Java 应用程序中创建的所有对象,而不管创建该对象的线程如何。 这包括原始类型的对象版本(例如`Byte``Integer``Long`等)。
...@@ -49,11 +49,11 @@ java -Xms500m -Xmx6g myprogram ...@@ -49,11 +49,11 @@ java -Xms500m -Xmx6g myprogram
会将初始堆大小设置为 500 MB,将最大堆大小设置为 6 GB。 会将初始堆大小设置为 500 MB,将最大堆大小设置为 6 GB。
## 增加栈大小 ## 增加栈大小
在 Windows 上,默认线程栈大小是从二进制文件(java.exe)中读取的。 从 Java SE 6 开始,此值在 32 位 VM 中为 320k,在 64 位 VM 中为 1024k。 在 x86 Solaris / Linux 上,在 32 位 VM 中为 320k,在 64 位 VM 中为 1024k。 在 Windows 上,默认线程栈大小是从二进制文件(java.exe)中读取的。 从 Java SE 6 开始,此值在 32 位 VM 中为 320k,在 64 位 VM 中为 1024k。 在 x86 Solaris / Linux 上,在 32 位 VM 中为 320k,在 64 位 VM 中为 1024k。
您可以使用 **–** **Xss** 自变量来增加栈大小。 您可以使用 **–** **Xss** 自变量来增加栈大小。
例如: 例如:
...@@ -61,4 +61,4 @@ java -Xms500m -Xmx6g myprogram ...@@ -61,4 +61,4 @@ java -Xms500m -Xmx6g myprogram
java -Xss4m myprogram java -Xss4m myprogram
``` ```
将堆栈大小设置为 4 MB。 将栈大小设置为 4 MB。
\ No newline at end of file \ No newline at end of file
...@@ -70,13 +70,13 @@ jshell> new String("Hello") ...@@ -70,13 +70,13 @@ jshell> new String("Hello")
$4 ==> "Hello" $4 ==> "Hello"
``` ```
## JShell 自动完成 ## JShell 自动补全
JShell 具有内置的自动完成功能(也称为 Tab 补全功能),通过该功能,您只需按 Tab 键就可以最小化键入。 开始键入并按 Tab 键。 这将完成您开始键入的单词(如果只有一个选项可用)或显示可能的选项列表。 看下面的例子。 我们开始输入“ Str”,然后按 Tab 键: JShell 具有内置的自动补全功能(也称为 Tab 补全功能),通过该功能,您只需按 Tab 键就可以最小化键入。 开始键入并按 Tab 键。 这将完成您开始键入的单词(如果只有一个选项可用)或显示可能的选项列表。 看下面的例子。 我们开始输入“ Str”,然后按 Tab 键:
![jshell autocomplete function](img/87659f259091de125b17df3c6272aba2.jpg) ![jshell autocomplete function](img/87659f259091de125b17df3c6272aba2.jpg)
jshell 自动完成功能 jshell 自动补全功能
## JShell 自定义导入 ## JShell 自定义导入
......
...@@ -53,7 +53,7 @@ public class Java9EmptyImmutableListExample { ...@@ -53,7 +53,7 @@ public class Java9EmptyImmutableListExample {
} }
``` ```
## 在 Java 9 中使用 Elements 创建不可变列表 ## 在 Java 9 中使用元素创建不可变列表
有 10 种工厂方法可创建最多 10 个元素的不可变列表(来源: [Java 9 List 接口 Javadoc](https://docs.oracle.com/javase/9/docs/api/java/util/List.html) ): 有 10 种工厂方法可创建最多 10 个元素的不可变列表(来源: [Java 9 List 接口 Javadoc](https://docs.oracle.com/javase/9/docs/api/java/util/List.html) ):
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
![Java 9 immutable Map example](img/8500a2110e160de82f8947dfe191273f.jpg) ![Java 9 immutable Map example](img/8500a2110e160de82f8947dfe191273f.jpg)
Java 9 不可变地图示例 Java 9 不可变映射示例
在 Java 9 之前,创建不变 Map 是某种冗长的任务。 例如,要使用 Java 9 之前的版本创建一个空的不可变 Map,我们使用以下代码: 在 Java 9 之前,创建不变 Map 是某种冗长的任务。 例如,要使用 Java 9 之前的版本创建一个空的不可变 Map,我们使用以下代码:
...@@ -30,13 +30,13 @@ public class UnmodifiableMapExample { ...@@ -30,13 +30,13 @@ public class UnmodifiableMapExample {
``` ```
## 什么是不可变地图 ## 什么是不可变映射
一旦在 Java 中创建了不可变对象,就无法更改值。 不可变的地图也不例外。 您可以**不能** 一旦在 Java 中创建了不可变对象,就无法更改值。 不可变的映射也不例外。 您可以**不能**
* 键和值无法添加,删除或更新。 如果您尝试这样做,将在`java.lang.UnsupportedOperationException`中解决 * 键和值无法添加,删除或更新。 如果您尝试这样做,将在`java.lang.UnsupportedOperationException`中解决
* 修改地图条目。 尝试这样做会导致`java.lang.UnsupportedOperationException` * 修改映射条目。 尝试这样做会导致`java.lang.UnsupportedOperationException`
*地图中使用`null`键和值。 如果您尝试向地图添加空键或空值,则最终会显示`java.lang.NullPointerException` *映射中使用`null`键和值。 如果您尝试向映射添加空键或空值,则最终会显示`java.lang.NullPointerException`
## 在 Java 9 中创建空的不可变映射 ## 在 Java 9 中创建空的不可变映射
...@@ -104,7 +104,7 @@ public class Java9ImmutableMapExample { ...@@ -104,7 +104,7 @@ public class Java9ImmutableMapExample {
} }
``` ```
## 使用 Map.ofEntries()方法在 Java 9 中创建不可变地图 ## 使用`Map.ofEntries()`方法在 Java 9 中创建不可变映射
Java 9 中的 Map 接口提供了另一种实用程序方法来创建不可变映射– ofEntries。 该方法的签名如下所示: Java 9 中的 Map 接口提供了另一种实用程序方法来创建不可变映射– ofEntries。 该方法的签名如下所示:
......
# Java Singleton 设计模式示例 # Java 单例设计模式示例
> 原文: [https://javatutorial.net/java-singleton-design-pattern-example](https://javatutorial.net/java-singleton-design-pattern-example) > 原文: [https://javatutorial.net/java-singleton-design-pattern-example](https://javatutorial.net/java-singleton-design-pattern-example)
众所周知,设计模式是为解决特定问题而创建的。 Singleton 解决了仅创建一个类的一个对象的问题。 单例设计模式是最流行的设计模式之一,它限制任何类只能有一个对象。 并在需要时使用该对象。 在某些情况下,我们只需要一个类的对象,例如对于数据库连接,我们只需要一个对象来处理与查询相关的每个数据库,而不是每次都创建新对象。 我们仅创建一个数据库连接对象并为其分配全局访问权限,因此可以在任何地方访问它。 众所周知,设计模式是为解决特定问题而创建的。 Singleton 解决了仅创建一个类的一个对象的问题。 单例设计模式是最流行的设计模式之一,它限制任何类只能有一个对象。 并在需要时使用该对象。 在某些情况下,我们只需要一个类的对象,例如对于数据库连接,我们只需要一个对象来处理与查询相关的每个数据库,而不是每次都创建新对象。 我们仅创建一个数据库连接对象并为其分配全局访问权限,因此可以在任何地方访问它。
## 急切初始化的单例设计模式 ## 立即初始化的单例设计模式
顾名思义,**急于初始化**意味着在实际需要一个类的实例之前就已经创建了该实例。 通常,它是在系统启动时完成的。 在热切的初始化单例模式中,无论是否有其他类实际请求其实例,都将创建单例实例。 这种方法效果很好,但是有一个缺点。 不论是否在运行时都需要创建实例。 如果此实例不是大对象,并且您可以在不使用它的情况下生存下去,那么这是最好的方法。 顾名思义,**急于初始化**意味着在实际需要一个类的实例之前就已经创建了该实例。 通常,它是在系统启动时完成的。 在热切的初始化单例模式中,无论是否有其他类实际请求其实例,都将创建单例实例。 这种方法效果很好,但是有一个缺点。 不论是否在运行时都需要创建实例。 如果此实例不是大对象,并且您可以在不使用它的情况下生存下去,那么这是最好的方法。
## 具有延迟初始化的 Singleton 设计模式 ## 具有延迟初始化的单例设计模式
正如我们非常了解**延迟初始化**一样,它仅遵循延迟人的逻辑,他从来不做任何事情,直到它迫切需要时为止,这与延迟初始化相同。 类的对象仅在需要时才创建,而不像上面那样。 因此,在单例对象中,仅在第一次需要创建对象时才创建一次。 正如我们非常了解**延迟初始化**一样,它仅遵循延迟人的逻辑,他从来不做任何事情,直到它迫切需要时为止,这与延迟初始化相同。 类的对象仅在需要时才创建,而不像上面那样。 因此,在单例对象中,仅在第一次需要创建对象时才创建一次。
## 使用 Singleton 设计模式的好处 ## 使用单例设计模式的好处
**节省内存**:很明显,每当我们创建任何类的对象时,它都会占用内存空间,因此创建许多对象意味着会占用更多内存空间。 由于单例类可能只有一个对象,因此可以节省内存。 **节省内存**:很明显,每当我们创建任何类的对象时,它都会占用内存空间,因此创建许多对象意味着会占用更多内存空间。 由于单例类可能只有一个对象,因此可以节省内存。
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
上图显示并说明了单例模式的实现 上图显示并说明了单例模式的实现
## 渴望的单例设计模式 Java 示例 ## 立即初始化的单例设计模式示例
```java ```java
public class EagerSingleton { public class EagerSingleton {
...@@ -56,7 +56,7 @@ public class EagerSingleton { ...@@ -56,7 +56,7 @@ public class EagerSingleton {
``` ```
## 渴望的单例设计模式 Java 示例 ## 延迟初始化的单例设计模式示例
```java ```java
public class Lazy Singleton { public class Lazy Singleton {
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
## 现实场景中代理设计模式的实现 ## 现实场景中代理设计模式的实现
我们可以创建一个`Image`接口,并执行`Image`接口的实体类。 `ProxyImage`是一个代理类,用于减少`RealImage`对象栈的内存印象。 我们可以创建一个`Image`接口,并执行`Image`接口的实体类。 `ProxyImage`是一个代理类,用于减少`RealImage`对象栈的内存印象。
![Proxy pattern diagram for Java example](img/b09b9079df8aeed9c1d4ceb69d2d0265.jpg) ![Proxy pattern diagram for Java example](img/b09b9079df8aeed9c1d4ceb69d2d0265.jpg)
......
# Java Observer 设计模式示例 # Java 观察者设计模式示例
> 原文: [https://javatutorial.net/java-observer-design-pattern-example](https://javatutorial.net/java-observer-design-pattern-example) > 原文: [https://javatutorial.net/java-observer-design-pattern-example](https://javatutorial.net/java-observer-design-pattern-example)
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
想想您最喜欢的会员服务。 也许是体育馆,或者是 Netflix,或者完全不同。 在本示例中,我们将使用 Netflix,但基本上任何其他成员资格服务都可以使用。 如果 Netflix 更改了其每月会员资格的价格,而您要为此付费,则它应通知您。 实际上,它应该通知所有注册/订阅人员服务。 想想您最喜欢的会员服务。 也许是体育馆,或者是 Netflix,或者完全不同。 在本示例中,我们将使用 Netflix,但基本上任何其他成员资格服务都可以使用。 如果 Netflix 更改了其每月会员资格的价格,而您要为此付费,则它应通知您。 实际上,它应该通知所有注册/订阅人员服务。
## Java Observer 设计模式示例 ## Java 观察者设计模式示例
Subject.java Subject.java
......
...@@ -28,7 +28,7 @@ Java 是一种非常强大的语言。 每个人都喜欢它的主要原因是 ...@@ -28,7 +28,7 @@ Java 是一种非常强大的语言。 每个人都喜欢它的主要原因是
超类充当创建对象的公共接口或抽象类,但让子类决定在运行时实例化哪个类。 因此,可以说子类负责创建该类的实例。 超类充当创建对象的公共接口或抽象类,但让子类决定在运行时实例化哪个类。 因此,可以说子类负责创建该类的实例。
## Java Factory 设计模式示例 ## Java 工厂设计模式示例
让我们看一个通过实际示例并对其进行编码来实现工厂设计模式的示例。 让我们看一个通过实际示例并对其进行编码来实现工厂设计模式的示例。
......
# Java Builder 设计模式 # Java 构建器设计模式
> 原文: [https://javatutorial.net/java-builder-design-pattern](https://javatutorial.net/java-builder-design-pattern) > 原文: [https://javatutorial.net/java-builder-design-pattern](https://javatutorial.net/java-builder-design-pattern)
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
这种类型的设计模式通常使用流畅的界面来实现。 这种类型的设计模式通常使用流畅的界面来实现。
## 生成器设计模式的实现 ## 构建器设计模式的实现
Java 中的每个类都有一个由用户显式设置或默认设置的构造函数。 当可以借助许多不同的参数(可能是强制性的,而其他参数也可能是可选的)创建对象时,将使用构建器模式。 在这种情况下,事情变得复杂并且容易出错。 因此,在这种情况下,构建器模式会派上用场。 Java 中的每个类都有一个由用户显式设置或默认设置的构造函数。 当可以借助许多不同的参数(可能是强制性的,而其他参数也可能是可选的)创建对象时,将使用构建器模式。 在这种情况下,事情变得复杂并且容易出错。 因此,在这种情况下,构建器模式会派上用场。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册