├── .gitignore ├── LICENSE ├── README.md └── docs ├── .nojekyll ├── README.md ├── _coverpage.md ├── _navbar.md ├── _sidebar.md ├── assets └── images │ ├── add-blinkfox-checks-success.png │ ├── add-blinkfox-checks.png │ ├── idea-check.png │ ├── idea-checkstyle-plugin.png │ ├── import-idea-style-xml.png │ └── logo.png ├── checks ├── blinkfox-checks.xml ├── blinkfox-idea-java-style.xml └── google-checks.xml ├── favicon.ico ├── guide ├── blinkfox-java-style-guide.md ├── google-java-style-guide-cn.md └── google-java-style-guide.md ├── index.html └── styles ├── blinkfox-checks.md ├── blinkfox-idea-java-style.md └── google-checks.md /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ IDEA ### 2 | .idea 3 | *.iws 4 | *.iml 5 | *.ipr 6 | 7 | ### VS Code ### 8 | .vscode/ 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | docsify 4 | 5 |

6 | 7 |

8 | Blinkfox Java 编程风格指南,且包含 CheckStyle 和 IDEA 格式化文件。 9 |

10 | 11 | [![HitCount](http://hits.dwyl.io/blinkfox/java-style.svg)](http://hits.dwyl.io/blinkfox/java-style) [![GitHub license](https://img.shields.io/github/license/blinkfox/java-style.svg)](https://github.com/blinkfox/java-style/blob/master/LICENSE) [![Docs Site](https://img.shields.io/badge/Docs%20Site-%E6%96%87%E6%A1%A3%E7%BD%91%E7%AB%99-orange)](https://blinkfox.github.io/java-style) 12 | 13 | > 这是关于 Java 编程风格相关的仓库。核心来自于 Google 的 Java 编程风格指南([Google Java Style Guide](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s3.3.3-import-ordering-and-spacing),并对该份英文指南做了翻译,并最终整理出了适合我和更多人的一份规范来。 14 | 15 | - [查看文档 https://blinkfox.github.io/java-style](https://blinkfox.github.io/java-style) 16 | 17 | ## 主要内容 18 | 19 | 本仓库核心内容如下: 20 | 21 | ```bash 22 | - docs 23 | - checks 24 | - blinkfox-checks.xml # 经过部分新增、修改和详细注释的,符合 Blinkfox 编程风格的 checkstyle 文件. 25 | - blinkfox-idea-java-style.xml # 符合 Blinkfox 编程风格的,可导入 Intellij IDEA 中的 Java code style 的格式化文件. 26 | - google-checks.xml # 未经修改的符合 Google 编程风格的原生 checkstyle 文件. 27 | - guide 28 | - blinkfox-java-style-guide.md # 基于 Google 原生的编程风格而新增、修改的,且符合 Blinkfox 编程风格的简要中文指南 29 | - google-java-style-guide-cn.md # 翻译的 Google 原生的编程风格指南的中文文档 30 | - google-java-style-guide.md # Google 原生的编程风格指南英文文档 31 | - LICENSE # 仓库协议,Apache License2.0 32 | ``` 33 | 34 | 本仓库的核心产出结果主要是《Google Java 编程风格指南.md》、《Blinkfox Java 编程风格指南》、《blinkfox-checks.xml》、《blinkfox-idea-java-style.xml》。 35 | 36 | 其中《Google Java 编程风格指南.md》和《Blinkfox Java 编程风格指南》是文档型,主要供大家阅读参考。而[《blinkfox-checks.xml》](https://github.com/blinkfox/java-style/blob/master/checks/blinkfox-checks.xml)和[《blinkfox-idea-java-style.xml》](https://github.com/blinkfox/java-style/blob/master/checks/blinkfox-idea-java-style.xml) 才是真正可实际用于工具和项目中的代码风格检查和格式化文件。 37 | 38 | ## 开源协议 39 | 40 | 本项目基于 Apache License 2.0 协议开源。 41 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/.nojekyll -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # 💡快速使用 2 | 3 | [Blinkfox Java 编程风格指南](guide/blinkfox-java-style-guide.md)是 Blinkfox 根据 [Google Java 编程风格](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s3.3.3-import-ordering-and-spacing)规范并根据自身使用情况而修改出的一份 Java 编程风格指南。相对于 Google 的 Java 编程风格文档而言,修改了部分规范,增加了一些更加确定性的规则说明,这样能最大程度上的让团队的代码风格统一、易读。 4 | 5 | 本文档仓库中[《blinkfox-checks.xml》](styles/blinkfox-checks.md)和[《blinkfox-idea-java-style.xml》](styles/blinkfox-idea-java-style.md) 是真正可实际用于项目和工具中的代码风格检查和格式化文件。 6 | 7 | 下面将介绍如何在项目或 Intellij IDEA 中集成使用相关的配置检查文件格式化文件等。 8 | 9 | ## 1 Maven 中集成 blinkfox-checks.xml :id=maven-blinkfox-checks 10 | 11 | 以下以 Maven 项目为例,介绍如何在 Java Maven 项目中集成使用 `blinkfox-checks.xml` 的 checkstyle 文件,你也可以查看此文件的内容,其中有详细的中文注释,你也可以对部分内容进行新增或修改,直到符合你自己或团队的代码风格要求。 12 | 13 | ### 1.1 下载 blinkfox-checks.xml 14 | 15 | 首先,下载复制 [blinkfox-checks.xml](#) 文件到你的项目中,建议你将该文件放在与 `pom.xml` 文件**同级**的目录的中,当然你也可以放其他目录中,只不过需要额外在 Maven checkstyle 插件中配置目录位置。 16 | 17 | ### 1.2 集成 maven-checkstyle-plugin 18 | 19 | 然后,在你项目的 `pom.xml` 文件的 `build` -> `plugins` 层级下,添加 `maven-checkstyle-plugin` 插件,复制如下即可: 20 | 21 | ```xml 22 | 23 | org.apache.maven.plugins 24 | maven-checkstyle-plugin 25 | 26 | 3.1.2 27 | 28 | 29 | com.puppycrawl.tools 30 | checkstyle 31 | 32 | 9.3 33 | 34 | 35 | 36 | 37 | blinkfox-checks.xml 38 | UTF-8 39 | true 40 | 41 | true 42 | false 43 | 44 | 45 | 46 | validate 47 | 48 | validate 49 | 50 | check 51 | 52 | 53 | 54 | 55 | ``` 56 | 57 | ### 1.3 开始检查代码 58 | 59 | 然后在项目的命令行中执行下面的命令即可,就能在控制台输出所有不符合规则的错误代码所在的文件和行、列、规则了。 60 | 61 | ```bash 62 | mvn clean validate 63 | ``` 64 | 65 | > **注**:由于 checkstyle 检查的是源码,且 `validate` 在 Maven 命令的生命周期中是很早的一个阶段,你执行 `compile`、`test`、`install`、`deploy` 等等也都会执行该 `validate` 阶段,也就是说也都会检查代码是否符合规则。 66 | 67 | 基于 Maven 插件的方式便于做持续集成,能使团队成员及早的规避代码风格不统一的问题。 68 | 69 | ## 2 IDEA 中使用 blinkfox-checks.xml :id=idea-blinkfox-checks 70 | 71 | ### 2.1 下载 CheckStyle-IDEA 插件 72 | 73 | 首先确保在你的 Intellij IDEA 中已经安装了 `CheckStyle-IDEA` 插件。如果没有安装你可以在 IDEA 中直接在线安装,如果网络不理想的话,可以[前往这里下载](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea)来离线安装此插件亦可。当然,安装完毕之后需要重启 IDEA。 74 | 75 | ![CheckStyle-IDEA](assets/images/idea-checkstyle-plugin.png) 76 | 77 | ### 2.2 配置 blinkfox-checks.xml 78 | 79 | 然后,在**设置** `Preferences`(或 `Settings`) -> `Other Settings` 中,找到并点击 `Checkstyle` 选项,通过 `+` 号按钮添加我们自己的 Checkstyle 配置文件,添写描述信息、添加你本地或远程地址上的 Checkstyle 文件,点击“下一步”,“完成”即可。 80 | 81 | ![添加](assets/images/add-blinkfox-checks.png) 82 | 83 | ![列表](assets/images/add-blinkfox-checks-success.png) 84 | 85 | ### 2.3 在 IDEA 中进行检查 86 | 87 | 最后,在 IDEA 中点开 `CheckStyle` 窗口,选中之前添加的 `Blinkfox Checks` 配置,之后就可以对某个具体类、模块或项目进行检查了。 88 | 89 | ![在 IDEA 中做检查](assets/images/idea-check.png) 90 | 91 | ## 3 IDEA 中使用 blinkfox-idea-java-style.xml :id=idea-java-style 92 | 93 | ### 3.1 导入配置文件到 IDEA 中 94 | 95 | `blinkfox-idea-java-style.xml` 是一个用于导入到 Intellij IDEA 中的代码格式化配置文件。可以[前往这里下载](https://github.com/blinkfox/java-style/blob/master/checks/blinkfox-idea-java-style.xml),存放到你自己的某个本地文件目录中。 96 | 97 | 首先,在 **设置** `Preferences`(或 `Settings`) -> `Editor` -> `Code Style` -> `Java` 选项中,点击 Schema 后的设置按钮,点击 `Import Schema` -> `Intellij IDEA code style XML` 文件,选择你刚刚下载的 `blinkfox-idea-java-style.xml` 文件即可。 98 | 99 | ![在 IDEA 中做检查](assets/images/import-idea-style-xml.png) 100 | 101 | ### 3.2 格式化和包导入优化 102 | 103 | 导入完成之后,可以在单个文件、文件夹、模块、项目的 Java 文件中,使用 `Ctrl + Alt + L` 来格式化文件,使代码更加符合规范和统一的风格。当然你还可以使用 `Ctrl + Alt + O` 来优化包的导入顺序。 104 | 105 | ## 开源协议 106 | 107 | 本项目基于 Apache License 2.0 协议开源。 108 | -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 | ![logo](assets/images/logo.png) 2 | 3 | # Blinkfox Java Style 4 | 5 | > Blinkfox Java 编程风格指南以及风格配置文件 6 | 7 | [![GitHub license](https://img.shields.io/github/license/blinkfox/java-style.svg)](https://github.com/blinkfox/java-style/blob/master/LICENSE) 8 | 9 | - 本编程风格指南基于 Google 编程风格指南修改而来 10 | - 包含 `checkstyle` 文件和可导入 Intellij IDEA 中的 Java `code style` 11 | 12 | [🦊 GitHub](https://github.com/blinkfox/java-style/) 13 | [⬇ 开始使用](README) 14 | -------------------------------------------------------------------------------- /docs/_navbar.md: -------------------------------------------------------------------------------- 1 | - [💡快速使用](README) 2 | - 📖编程风格指南 3 | - [Blinkfox Java 编程风格指南](guide/blinkfox-java-style-guide) 4 | - [Google Java 编程风格指南中文版](guide/google-java-style-guide-cn) 5 | - [Google Java Style Guide](guide/google-java-style-guide) 6 | - 📝编程风格文件 7 | - [blinkfox-checks.xml](styles/blinkfox-checks) 8 | - [blinkfox-idea-java-style.xml](styles/blinkfox-idea-java-style) 9 | - [google-checks.xml](styles/google-checks) 10 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - [💡快速使用](README) 2 | - 📖编程风格指南 3 | - [Blinkfox Java 编程风格指南](guide/blinkfox-java-style-guide) 4 | - [Google Java 编程风格指南中文版](guide/google-java-style-guide-cn) 5 | - [Google Java Style Guide](guide/google-java-style-guide) 6 | - 📝编程风格文件 7 | - [blinkfox-checks.xml](styles/blinkfox-checks) 8 | - [blinkfox-idea-java-style.xml](styles/blinkfox-idea-java-style) 9 | - [google-checks.xml](styles/google-checks) 10 | -------------------------------------------------------------------------------- /docs/assets/images/add-blinkfox-checks-success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/add-blinkfox-checks-success.png -------------------------------------------------------------------------------- /docs/assets/images/add-blinkfox-checks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/add-blinkfox-checks.png -------------------------------------------------------------------------------- /docs/assets/images/idea-check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/idea-check.png -------------------------------------------------------------------------------- /docs/assets/images/idea-checkstyle-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/idea-checkstyle-plugin.png -------------------------------------------------------------------------------- /docs/assets/images/import-idea-style-xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/import-idea-style-xml.png -------------------------------------------------------------------------------- /docs/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/assets/images/logo.png -------------------------------------------------------------------------------- /docs/checks/blinkfox-checks.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 83 | 84 | 85 | 86 | 88 | 89 | 90 | 91 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 112 | 113 | 115 | 116 | 117 | 119 | 120 | 121 | 122 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 143 | 145 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 160 | 161 | 162 | 163 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 208 | 209 | 210 | 211 | 212 | 214 | 215 | 216 | 217 | 218 | 220 | 221 | 222 | 223 | 224 | 226 | 227 | 228 | 229 | 230 | 232 | 233 | 234 | 235 | 236 | 238 | 239 | 240 | 241 | 242 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 271 | 272 | 273 | 274 | 275 | 277 | 278 | 279 | 280 | 282 | 283 | 285 | 287 | 289 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 328 | 329 | 330 | 331 | 333 | 334 | 335 | 336 | 337 | 342 | 343 | 344 | 345 | 346 | 349 | 350 | 351 | 352 | 353 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 426 | 427 | 429 | 430 | 431 | 432 | 433 | -------------------------------------------------------------------------------- /docs/checks/blinkfox-idea-java-style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 28 | 33 | 34 | 35 | 37 | 38 | 39 | 62 | 63 | 64 | 66 | 67 | -------------------------------------------------------------------------------- /docs/checks/google-checks.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 69 | 70 | 71 | 73 | 74 | 75 | 81 | 82 | 83 | 84 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 98 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 115 | 117 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 164 | 165 | 166 | 167 | 169 | 170 | 171 | 172 | 174 | 175 | 176 | 177 | 179 | 180 | 181 | 182 | 184 | 185 | 186 | 187 | 189 | 190 | 191 | 192 | 194 | 195 | 196 | 197 | 199 | 200 | 201 | 202 | 204 | 205 | 206 | 207 | 209 | 210 | 211 | 212 | 214 | 216 | 218 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 248 | 249 | 250 | 252 | 253 | 254 | 255 | 260 | 261 | 262 | 263 | 266 | 267 | 268 | 269 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 283 | 284 | 285 | 286 | 287 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blinkfox/java-style/cce3b132cb9c8bcb3d91b089f0cd28164dd4df1d/docs/favicon.ico -------------------------------------------------------------------------------- /docs/guide/blinkfox-java-style-guide.md: -------------------------------------------------------------------------------- 1 | # 📖 Blinkfox Java 编程风格指南 2 | 3 | ## 1 前言 4 | 5 | 这份文档是 Blinkfox 根据 [Google Java 编程风格](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s3.3.3-import-ordering-and-spacing)规范而根据自身使用情况而修改的一份 Java 编程风格指南。本文档相对于 Google 的 Java 编程风格文档而言,修改了部分规范,增加了一些更加确定性的规则说明,这样能最大程度上的让代码风格统一、易读。且本文档的语言描述会更加的精简,文档最后也罗列了一些具体的[新增或修改点](guide/blinkfox-java-style-guide?id=modification-point)。 6 | 7 | ## 2 源文件基础 8 | 9 | - 源文件名必须与顶级(最外层的)类的名称相同,且使用大驼峰(`UpperCamelCase`)的方式来命名,源文件扩展名为 `.java`。 10 | - 源文件使用 **`UTF-8`** 编码。 11 | - 源文件中只能使用**换行符**和**空格符**(ASCII 字符:`0x20`)作为空白符,**禁止使用 `Tab` 制表符**来用于缩进。 12 | - 对于具有[特殊转义序列](http://docs.oracle.com/javase/tutorial/java/data/characters.html)(例如:`\b`, `\t`, `\n`, `\f`, `\r`, `\"`, `\'`, `\\`等)的字符,都采用这种转义字符的方式表示,而不采用对应字符的八进制数(如:`\012`)或 Unicode (如:`\u000a`)来表示。 13 | - 对于其余的非 ASCII 字符,就直接使用 Unicode 字符即可(如:`∞`) 14 | 15 | ## 3 源文件结构 16 | 17 | ### 3.1 结构组成 18 | 19 | - 源文件按**从上到下的顺序**,由以下几部分组成,且每个部分之间应该**只有一个空行**作为分隔。: 20 | 1. 许可证 (`License`)或版权信息(`copyright`)(该组成部分是可选的) 21 | 2. 包声明(`package`)语句 22 | 3. 包导入(`import`)语句 23 | 4. 类(`class`)声明 24 | - 如果源文件中需要包含许可证或版权信息,那么应该把它放在文件最前面。 25 | - 包声明(`package`)语句和包导入(`import`)语句不受制于列长度限制,都是独立成行。 26 | - 包导入(`import`)语句中**都不使用通配符**),不管是否是静态导入(`static import`)。 27 | - 包导入(`import`)语句按从上到下的顺序分为**静态导入**(`static import`)块和**非静态导入**块两部分,如果同时具有静态和非静态导入,则**使用一个空行将两块分开。每个块的若干导入语句之间不空行,且导入的顺序按名称的 ASCII 顺序排序**。 28 | - 静态内部类中不使用静态导入(`static import`)。 29 | - 每个源文件中只能有一个顶级类(`class`)声明。 30 | 31 | ### 3.2 类成员顺序 32 | 33 | - 类成员的顺序对代码的易读性有很大的影响,这里归纳总结了一些类成员从上到下的建议排列顺序: 34 | 1. 具有 `static final` 关键字修饰的属性; 35 | 2. 具有 `static` 关键字修饰的属性; 36 | 3. 普通字段属性从上到下再按 `public`、`protected`、`default`、`private` 的访问级别顺序排列; 37 | 4. 同访问级别的属性之间再按引用对象类型和原始类型(或包装)类型的顺序排列; 38 | 5. `static {}` 初始化块; 39 | 6. 一个或多个构造方法,从上到下按参数由少到多的顺序排列; 40 | 7. 其他方法; 41 | - **重载方法必须按顺序排列在一起**,中间不要插入其它方法或私有成员。 42 | 43 | ## 4 格式 44 | 45 | ### 4.1 语句块的格式 46 | 47 | - 在 `if`, `else`, `for`, `do` 和 `while` 等语句中,即使只有一条语句或者内容为空时,也需要写上大括号。 48 | - **对于语句块,大括号都遵循 `K&R` 风格**(Kernighan 和 Ritchie 风格): 49 | - 左大括号前不换行 50 | - 左大括号后换行 51 | - 右大括号前换行 52 | - 如果右大括号结束是一个语句块或者方法体、构造函数体或者有命名的类体,则需要换行。当右括号后面接 `else` 或逗号(`,`)时,不换行。示例: 53 | 54 | ```java 55 | return () -> { 56 | while (condition()) { 57 | method(); 58 | } 59 | }; 60 | 61 | return new MyClass() { 62 | @Override public void method() { 63 | if (condition()) { 64 | try { 65 | something(); 66 | } catch (ProblemException e) { 67 | recover(); 68 | } 69 | } else if (otherCondition()) { 70 | somethingElse(); 71 | } else { 72 | lastThing(); 73 | } 74 | } 75 | }; 76 | ``` 77 | 78 | - **对于空语句块,也需要遵循 `K&R` 风格**,如果是**无参构造方法**,内容可以保持为空,或者使用 `super();` 填充内容,或者默认不写该构造方法。如果是其他类型的空方法或空语句块,需要在空语句块中使用注释说明为什么是空的。示例: 79 | 80 | ```java 81 | // 这是不可以的 82 | void doNothing() {} 83 | 84 | // 这是不可以的 85 | void doNothingElse() { 86 | } 87 | 88 | // 这是可以的 89 | void doNothingElse() { 90 | // 这里需要写明内容为空的现实原因和真正意图. 91 | } 92 | ``` 93 | 94 | ### 4.2 缩进机制 95 | 96 | - **使用 `4` 个空格作为基础尺度来缩进代码**。即每产生一个新的语句块,缩进就增加 `4` 个空格。当这个语句块结束时,缩进恢复到上一层级的缩进级别。此缩进要求对整个语句块中的代码和注释都适用。 97 | - **每条语句结束都需要换行,换行缩进需 `+8` 个空格**。一条语句自动换行时,第一行后的每一行都比上一行多缩进 `8` 个空格。如果两个连续行中使用了同级别的语法元素(如:`.` 操作符),则他们要使用相同的缩进。 98 | 99 | 代码示例如下: 100 | 101 | ```java 102 | // 下面的示例演示了一条语句换行时的缩进为 8 个空格. 103 | private void assertMethod(int[] array1, int[] array2, boolean expected) { 104 | Assertions.assertEquals(expected, 105 | new LongLongLongTestClassName().callLongLongLongTestMethodName(array1, array2)); 106 | } 107 | ``` 108 | 109 | ### 4.3 列长度限制 110 | 111 | - 代码的**列长度限制为 `120` 个字符**,该“字符”表示任何 Unicode 代码点。但也有一些例外情况: 112 | - Javadoc 文档注释中的一个长 URL; 113 | - 如前面所述的 `package` 和 `import` 语句; 114 | - 注释中的命令行代码,便于剪切粘贴到 shell 中; 115 | 116 | ### 4.4 换行机制 117 | 118 | - 换行有助于使代码更清晰、易读,换行的主要原则是:**选择在更高级的语法逻辑处换行**。包括下面的一些情形: 119 | - 当在一个非赋值运算的语句换行时,在运算符号之前换行,如:在字符串拼接的 `+` 号前换行。下面的情况也类似: 120 | - 在点(`.`)操作符之前换行 121 | - 在方法引用中双冒号(`::`)操作符之前换行 122 | - 在与或逻辑运算符(`&&`、`||`)之前换行 123 | - 在 `catch` 块中的管道符号之前换行(`catch (FooException | BarException e)`) 124 | - 当要在赋值运算符语句处换行时,一般在赋值符号之后换行(即 `=` 号之后换行)。 125 | - 在增强 for 循环(`foreach`)语句中的冒号(`:`)之后换行。 126 | - 方法名或构造函数名与仍然左括号(`(`)留在同一行。 127 | - 逗号(`,`)与其前面的内容留在同一行。 128 | - 在 `Lambda` 表达式中的箭头旁边永远不要换行,除非当 `Lambda` 表达式的主体由单个无括号的表达式组成时,可能会在箭头之后换行。示例: 129 | 130 | ```java 131 | MyLambda lambda = 132 | (String label, Long value, Object obj) -> { 133 | ... 134 | }; 135 | 136 | Predicate predicate = str -> 137 | longExpressionInvolving(str); 138 | ``` 139 | 140 | - **类成员之间需要单个空行隔开**:例如:字段,构造函数,方法,内部类,静态初始化块,实例初始化块。在类的第一个成员之前或最后一个成员之后,使用空行。两个连续属性之间的空行是可选的,根据需要使用空行来创建字段间的逻辑分组。但是,如果是业务属性字段,强烈建议对其进行文档注释,且这些业务属性字段之间也需要空行。 141 | - **一个空行也可以出现在任何提高可读性的地方**,例如,在一个方法或代码块中,不同的子逻辑之间用空行隔开。 142 | - 不要使用多个连续的空行,**最多只能空一行**。 143 | - 建议在每个 Java 源文件末尾留一个空行,**建议而不强制**。这也是由于“历史原因”引起的,当然如果你有心的话,你会发现 JDK 的源码中全是这样的。 144 | 145 | ### 4.5 空格机制 146 | 147 | 除了语法、其他规则、词语分隔、注释和 Javadoc 外,水平的 ASCII 空格只在以下情况出现: 148 | 149 | - 所有保留的关键字与紧接它之后同一行的左小括号(`(`)之间需要用空格隔开,例如:`if`, `for` `catch`。 150 | - 所有保留的关键字与在它之前的右大括号(`}`)之间需要空格隔开,例如:`else`、`catch`。 151 | - 在左大括号之前都需要空格隔开。 152 | - **例外情况**:`@SomeAnnotation({a, b})`(不使用空格)。 153 | - **例外情况**:`String[][] x = {{"foo"}};`(第二个 `{` 之前不使用空格)。 154 | - 所有的二元和三元运算符的两边,都需要使用空格隔开。以下“类似操作符”的情况也适用: 155 | - 连接泛型类型的 `&` 符号:`` 156 | - 处理多个异常 `catch` 中的管道操作符:`catch (FooException | BarException e)` 157 | - 增强 `for` 循环(`foreach`)中的冒号:`:` 158 | - `Lambda` 表达式中的箭头符号(`->`) 159 | 例外情况: 160 | - 方法引用中的双冒号(`::`),写法类似于 `Object::toString` 161 | - 点号操作符(`.`),写法类似于 `object.toString()` 162 | - 逗号(`,`)、冒号(`:`)、分号(`;`)和右小括号(`)`)、Lambda箭头符号(`->`)之后,需要空格隔开。 163 | - 使用`//`双斜线开始一行注释时,双斜线两边都应该用空格隔开。并且可使用多个空格。(可选的,例如:`a = 0; // 赋值为0`) 164 | - 在声明的变量类型和变量名之间需要用空格隔开:`List list` 165 | - 初始化一个数组时,大括号内的空格是可选的。 166 | - `new int[] {5, 6}` 和 `new int[] { 5, 6 }` 这两种都是可以的 167 | - 在类型注解和 `[]` 或者 `...` 之后使用空格。 168 | 169 | 示例如下: 170 | 171 | ```java 172 | /** 173 | * 这是一个用来演示代码格风格和格式的测试示例类. 174 | * 175 | *

注意:你不需要去管代码逻辑,着重看代码块、缩进、每一个空行以及空格等的使用.

176 | * 177 | * @author intelij idea on 2019-09-25. 178 | * @author blinkfox on 2020-03-18. 179 | * @since v1.2.0 180 | */ 181 | @Slf4j 182 | @Annotation(param1 = "value1", param2 = "value2") 183 | @SuppressWarnings( {"ALL"}) 184 | public class Foo { 185 | 186 | /** 187 | * 这是一个用于 xxxx 目的的数组. 188 | */ 189 | public static final int[] X = new int[] {1, 3, 5, 6, 7, 87, 1213, 2}; 190 | 191 | private int[] empty = new int[] {}; 192 | 193 | /** 194 | * 这是一个用于测试的测试示例方法,你不需要去管代码逻辑. 195 | * 196 | * @param x 变量 x 197 | * @param y 变量 y 198 | * @author intelij idea on 2019-09-25. 199 | * @since v1.2.0 200 | */ 201 | public void foo(int x, int y) { 202 | Runnable run1 = () -> { 203 | System.out.println("Hello World!"); 204 | System.out.println("Test Lambda."); 205 | }; 206 | Runnable run2 = this::bar; 207 | 208 | // 遇到晦涩难懂的代码,你需要写明注释,为什么要这么写. 209 | for (int i = 0; i < x; i++) { 210 | y += (y ^ 0x123) << 2; 211 | } 212 | 213 | // 这是这下面这一块儿处理逻辑的注释. 214 | try (MyResource r1 = getResource(); 215 | FileInputStream r2 = new FileInputStream(r1); 216 | BufferedOutputStream r3 = new BufferedOutputStream(r2)) { 217 | if (0 < x && x < 10) { 218 | while (x != y) { 219 | x = f(x * 3 + 5); 220 | } 221 | } else { 222 | // 一些重要的业务逻辑处理,你也需要写明注释. 223 | synchronized (this) { 224 | switch (e.getCode()) { 225 | //... 226 | } 227 | } 228 | } 229 | } catch (MyException | MyException2 e) { 230 | log.error("This is your error msg.", e); 231 | } catch (YourException expected) { 232 | // 如果异常被命名为 'expected' 或者 'ignore',则意味着可以不处理,但需用注释写明原因. 233 | } finally { 234 | int[] arr = (int[]) g(y); 235 | x = y >= 0 ? arr[y] : -1; 236 | Map sMap = new HashMap(); 237 | Bar.mess(null); 238 | } 239 | 240 | // 这是一个新的子逻辑代码块,也需要写明注释. 241 | while (true) { 242 | if (empty.length == 0) { 243 | break; 244 | } 245 | } 246 | } 247 | 248 | } 249 | 250 | ``` 251 | 252 | ### 4.6 不使用水平对齐 253 | 254 | - **尽量不使用水平对齐**。水平对齐是指通过添加多个空格,使本行的某一符号与上一行的某一符号上下对齐。以下是没有水平对齐和做了水平对齐的例子: 255 | 256 | ```java 257 | // 不使用水平对齐. 258 | private int x; // 这种挺好 259 | private Color color; // 同上 260 | 261 | // 使用了水平对齐. 262 | private int x; // 不推荐,未来变量名修改了,会继续编辑,增加了维护难度. 263 | private Color color; // 可能会使它对不齐 264 | ``` 265 | 266 | > **提示**:水平对齐虽然可以提高代码的可读性,但是增加了未来维护代码的麻烦。考虑到维护时只需要改变一行代码,之前的对齐可以不需要改动。为了对齐,你更有可能改了一行代码,同时需要更改附近的好几行代码,而这几行代码的改动,可能又会引起一些为了保持对齐的代码改动。那原本这行改动,我们称之为**爆炸半径**。这种改动,在最坏的情况下可能会导致大量的无意义的工作,即使在最好的情况下,也会影响版本历史信息,减慢代码 `review` 的速度,引起更多合并代码的冲突。 267 | 268 | ### 4.7 其他格式 269 | 270 | - **推荐使用分组小括号**。除非作者和审阅人(`reviewer`)都认为去掉小括号也不会使代码被误解,或是去掉小括号能让代码更易于阅读,否则我们不应该去掉小括号。 271 | - **枚举常量间用逗号隔开,多个枚举实例之间需要空行**。由于每个枚举实例默认都是 `public static final` 的,所以也需要附加文档注释,且需要换行,并添加额外的空行。示例如下: 272 | 273 | ```java 274 | public enum MyEnum { 275 | 276 | /** 277 | * 枚举实例 1 的注释. 278 | */ 279 | INSTANCE1, 280 | 281 | /** 282 | * 枚举实例 2 的注释. 283 | */ 284 | INSTANCE2, 285 | 286 | /** 287 | * 枚举实例 3 的注释. 288 | */ 289 | INSTANCE3 290 | 291 | // 其他方法... 292 | } 293 | ``` 294 | 295 | - **每个变量声明(字段或局部变量)只声明一个变量**,不使用诸如 `int a, b;` 之类的声明。 296 | - **例外情况**: `for` 循环的初始化头中可以使用多个变量声明。如:`for (int i = 0, len = arr.length; i < len; i++) {` 297 | - **局部变量在需要使用它的地方再声明**。不要在代码块的开头把所有局部变量一次性全部进行声明(不同于 C 语言),而是在第一次需要使用它时才声明,这样能最大程度地减小其作用范围。局部变量在声明时最好就进行初始化,或者声明后尽快进行初始化。 298 | - 数组的类型不同于 C 语言,中括号是类型的一部分:`String[] args`, 而非 `String args[]`。 299 | - switch 大括号之后缩进 `4` 个字符。每个 switch `case` 语句之后,有一个换行符,并按照大括号相同的处理方式缩进 `4` 个字符。在某个 `case` 结束后,恢复到之前的缩进,类似大括号的结束符。 300 | - 每个 switch 语句中,都需要显式声明 `default` 语句,即使没有任何代码。 301 | - 注解应用到类、属性、构造方法、方法上时,应紧接 Javadoc 之后,且独立成行。如果注解应用在参数或者局部变量上时,建议与他们写到一行。示例: 302 | 303 | ```java 304 | // 推荐写法. 多个注解独立成行。 305 | @Override 306 | @Nullable 307 | public String getNameIfPresent() { ... } 308 | 309 | // 不推荐. (注解和成员在同一行了) 310 | @Override public int hashCode() { ... } 311 | 312 | // 不推荐. (多个注解放在了同一行了) 313 | @Partial @Mock 314 | private DataLoader loader; 315 | 316 | // 推荐写法,注解修饰参数或局部变量时,放在同一行. 317 | public ModelAndView getUserInfo( 318 | @RequestParam("userId") String userId, 319 | @RequestParam("userName") String userName) { 320 | // this is content. 321 | } 322 | ``` 323 | 324 | - 长整型(`long`)的数字字面量使用大写的 `L` 作为后缀,不得使用小写(避免与数字 `1` 混淆)。例如:使用 `3000000000L`,而不是 `3000000000l`。 325 | - **不使用行尾注释**,建议在代码行或逻辑行之上做单行注释即可。 326 | - 类和成员变量的修饰符,按 `Java Lauguage Specification` 中介绍的先后顺序排序。具体是: 327 | 328 | ```java 329 | public protected private abstract default static final transient volatile synchronized native strictfp 330 | ``` 331 | 332 | ## 5 命名 333 | 334 | ### 5.1 驼峰命名法(CamelCase)的定义 335 | 336 | **驼峰式命名法**分大驼峰式命名法(`UpperCamelCase`)和小驼峰式命名法(`lowerCamelCase`)。有时,我们有多种合理的方式将一个英语词组转换成驼峰形式,如缩略语或不寻常的结构,例如:`IPv6` 或 `iOS`。以下是一个(几乎)确定性的转换方案。 337 | 338 | 名字从散文形式(`prose form`)开始: 339 | 340 | 1. 把短语转换为纯 ASCII 码,并且移除任何单引号。例如:`Müller’s algorithm` 将变成 `Muellers algorithm`。 341 | 2. 把这个结果切分成单词,在空格或其它标点符号(通常是连字符)处分割开。 342 | - **推荐**:如果某个单词已经有了常用的驼峰表示形式,按它的组成将它分割开(如`AdWords`将分割成`ad words`)。需要注意的是 `iOS` 并不是一个真正的驼峰表示形式,因此该推荐对它并不适用。 343 | 3. 现在将所有字母都小写(包括缩写),然后将单词的第一个字母大写: 344 | - 每个单词的第一个字母都大写,来得到大驼峰式命名。 345 | - 除了第一个单词,每个单词的第一个字母都大写,来得到小驼峰式命名。 346 | 4. 最后将所有的单词连接起来得到一个标识符。 347 | 348 | 请注意,几乎完全忽略了原始单词的大小写。示例: 349 | 350 | | 散文形式 | 正确 | 不正确 | 351 | | ------------ | ------------ | ------------ | 352 | | "XML HTTP request" | XmlHttpRequest | XMLHTTPRequest | 353 | | "new customer ID" | newCustomerId | newCustomerID | 354 | | "inner stopwatch" | innerStopwatch | innerStopWatch | 355 | | "supports IPv6 on iOS?" | supportsIpv6OnIos | supportsIPv6OnIOS | 356 | | "YouTube importer" | YouTubeImporter YoutubeImporter* | 无 | 357 | 358 | 加 `*` 号处表示可以接受,但不推荐。 359 | 360 | > **注意**:在英语中,某些带有连字符的单词形式不唯一。例如:`nonempty` 和 `non-empty` 都是正确的,因此方法名`checkNonempty`和`checkNonEmpty`也都是正确的。 361 | 362 | ### 5.2 类名、方法名 363 | 364 | - 标识符只能使用 ASCII 字母和数字,不使用特殊的前缀或后缀,如`name_`, `cName`, `c_name`。 365 | - **包名全部小写,连续的单词只是简单地连接起来,不使用下划线**。例如:使用 `com.example.deepspace`,而不是 `com.example.deepSpace` 或者 `com.example.deep_space`。 366 | - 类名、接口名、枚举类名、注解名都以大驼峰(`UpperCamelCase`)风格编写,但领域模型实体类(以 DO、DTO、BO、VO 等结尾)仍然可以使用连续大写,不建议大量使用 `DO`、`DTO`、`VO` 等,视业务情况使用,且考虑建立公共属性的父类,使用**继承**的方式,减少重复属性的定义和不同类之间的属性复制。 367 | - 抽象类命名使用 `Abstract` 开头,枚举类后建议以 `Enum` 或 `Type` 结尾,枚举实例值的单词之间用下划线(`_`)来分割。异常类命名使用`Exception`结尾;测试类命名以它要测试的类的名称开始,以 `Test` 结尾。接口名**不建议**使用 `I` 作为前缀,跟 JDK 学习,应该考虑使用名词或形容词。 368 | - 类名、枚举类名通常是名词或名词短语。接口名称也可以是名词或名词短语,也可以是形容词或形容词短语(例如:`Readable`)。自定义注解名可以是名称,动词或形容词。 369 | - 属性名、方法名、参数名、局部变量名都以小驼峰(`lowerCamelCase`)风格编写。属性名通常是是名称,方法名是动词或动词短语。 370 | - 泛型名以单个的大写字母命名(如:`E`, `K`, `V`)。 371 | - 类名、属性名、方法名等通常使用英文单词或短语来命名。但是,如果该词语是某些**专业领域**的中文名称(如:政法相关的内容),且**难以翻译**成简单而又准确的英语单词时,不推荐直接使用英文或中文汉字来命名,而是使用**中文拼音**或**中文简拼**,并且写上准确含义 Javadoc 注释。 372 | 373 | ### 5.3 常量名 374 | 375 | - 常量名的命名模式为 `CONSTANT_CASE`,字母全部大写,使用下划线来分隔单词,且常量的名字通常是名词或名词短语。 376 | 377 | 每个常量都是一个静态 `final` 字段,其内容是不可变的,且没有可检测的副作用。这包括原始类型、字符串、不可变类型和不可变类型的不可变集合。如果任何一个实例的观测状态是可变的,则它肯定不会是一个常量。**不可变对象不一定是常量**。例如: 378 | 379 | ```java 380 | // 下面是常量. 381 | static final int NUMBER = 5; 382 | static final ImmutableList NAMES = ImmutableList.of("Ed", "Ann"); 383 | static final ImmutableMap AGES = ImmutableMap.of("Ed", 35, "Ann", 32); 384 | static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable 385 | static final SomeMutableType[] EMPTY_ARRAY = {}; 386 | enum SomeEnum { ENUM_CONSTANT } 387 | 388 | // 下面的情况不是常量. 389 | static String nonFinal = "non-final"; 390 | final String nonStatic = "non-static"; 391 | static final Set mutableCollection = new HashSet(); 392 | static final ImmutableSet mutableElements = ImmutableSet.of(mutable); 393 | static final ImmutableMap mutableValues = 394 | ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2); 395 | static final Logger logger = Logger.getLogger(MyClass.getName()); 396 | static final String[] nonEmptyArray = {"these", "can", "change"}; 397 | ``` 398 | 399 | > **注**:根据这里常量的定义,阿里规约插件常量识别机制是有问题的,阿里规约插件认为只要有**static final**修饰符的就是常量,必须要大写,曲解了常量。 400 | 401 | ## 6 编程实践 402 | 403 | - 只要是合法的方法,就要加上 `@Override` 注解,这包括重写超类方法的类方法,实现接口方法的类方法以及重新指定父类接口方法的接口方法。**例外**:如果父方法为 `@Deprecated` 时,可以省略 `@Override`。 404 | - 不能忽视捕获的异常,**例外**:如果一个捕获的异常被命名为 `expected` 或者 `ignore`,则它可以不用处理,但仍然需要使用注释说明原因。 405 | 406 | ```java 407 | try { 408 | emptyStack.pop(); 409 | fail(); 410 | } catch (NoSuchElementException expected) { 411 | } 412 | ``` 413 | 414 | - 使用类名调用静态的类成员,而不是具体某个对象或表达式。示例如下: 415 | 416 | ```java 417 | Foo aFoo = ...; 418 | Foo.aStaticMethod(); // 赞同的方式. 419 | aFoo.aStaticMethod(); // 糟糕的方式. 420 | somethingThatYieldsAFoo().aStaticMethod(); // 非常糟糕的方式. 421 | ``` 422 | 423 | - 极少会去重写 `Object.finalize`。不要这么做。如果你非要使用它,请先仔细阅读和理解 [Effective Java](http://books.google.com/books?isbn=8131726592) 第 7 条:“Avoid Finalizers”,然后不要使用它。 424 | 425 | ## 7 Javadoc 426 | 427 | ### 7.1 如何写文档注释 428 | 429 | Javadoc 即文档注释,可以是多行,也可以是单行。当被注释的 Javadoc 只有简单的文字描述时,可以使用单行形式。请注意,这仅适用于没有 `@param`、`@return` 等块标记的情况。Javadoc 块的基本格式如下: 430 | 431 | ```java 432 | /** 433 | * Javadoc 摘要示例. 434 | * 435 | *

这是详细描述示例,这是行内注释的代码 {@code int} 的使用. 436 | * 这是注释内链接 {@link java.util.concurrent.atomic} 的使用示例.

437 | * 438 | * 这是一个 HTML 超链接的使用示例. 439 | * 440 | * @param p1 参数说明 441 | * @return 返回值说明 442 | * @see java.util.concurrent.atomic.AtomicInteger 443 | * @since v1.2.0 444 | * @author blinkfox add on 2020-03-20. 445 | * @author zhangshan modify on 2020-04-05. 446 | */ 447 | public int method(String p1) { ... } 448 | ``` 449 | 450 | 或者是以下单行形式: 451 | 452 | ```java 453 | /** 一小段的 Javadoc. */ 454 | ``` 455 | 456 | - 每个 Javadoc 都以一个简短的**摘要片段**开始,用于对所注释的类、属性、方法等进行简要的描述。并以**英文句号**(`.`)结尾。因为 Java 在生成 Javadoc 时,会以注释中第一个英文句号作为拆分点,解析出摘要片段和详细描述信息。 457 | - 空行是只包含最左侧星号(`*`)的空行会出现在段落之间和 Javadoc 注解标记(`@XXX`)之前(如果有的话)。除了第一个段落,每个段落第一个单词前都有标签`

`,并且它和第一个单词间没有空格。 458 | - Javadoc 中几个重要的注解标记: 459 | - 对于具有泛型参数的类或方法,对于具有参数的方法,Javadoc 中都必须加上 `@param` 注解标记和对应的注释; 460 | - 对于具有返回值的方法,Javadoc 中都必须加上 `@return` 注解标记和对应的注释; 461 | - 如果方法签名中有抛出异常,则必须有 `@throws` 注解标记和对应的注释; 462 | - 对于要弃用的类或方法,则使用 `@deprecated` 注解标记,并解释为什么弃用的原因。 463 | - 如果你的类、接口、方法等需要参考或关联其他类或接口,可以使用 `@see` 标签,在 Javadoc 注释内容中,则可以通过 `@link` 去链接,但注意,`@link` 只能链接该类或方法可访问类、属性或方法。 464 | - 当是第一次新增类或方法时。需要再新增的类或方法上额外加上作者、日期和新增该代码时的版本的注解,即要加上 `@author`、`@since` 注解,其中 `@author` 可以写多个,由于 Javadoc 中没有日期相关的 Javadoc 标签,建议将日期写在 `@author`的作者之后,格式形如:`@author blinkfox add on 2020-03-20.`。**注**:如果写上 Javadoc 不支持的 `@date` 标签,在生成 Javadoc 时会报错,且 `@date` 所表示的日期与具体的作者难以对应上。 465 | - 标准的 Javadoc 注解标记按以下顺序出现:`@param`, `@return`, `@throws`, `@deprecated`、`@author`, `@see`, `@since`, 这几种标记如果出现,描述都不能为空。当描述无法在一行中容纳,连续行需要至少在 `@` 符号的位置处缩进 `4` 个空格。 466 | - 行内的注释中如果包含“代码”,则可以使用 `@code` 包裹起来. 467 | 468 | ### 7.2 什么时候需要写 Javadoc 469 | 470 | - 在每个 `public` 类及它的每个 `public` 和 `protected` 成员处使用 Javadoc。 471 | - 对于**具有业务含义**的属性字段建议写上 Javadoc。 472 | - 对于包外不可见的类和方法,如有需要,也是要使用 Javadoc 的。 473 | - 如果一个注释是用来定义一个类,方法,字段的整体目的或行为,即时是 `private` 的,那么这个注释应该写成 Javadoc,这样更统一、更友好。 474 | 475 | ### 7.3 可以不需要 Javadoc 的例外情况 476 | 477 | - 对于 `getter` 和 `setter` 方法,Javadoc 是可选的,但建议在其字段属性上写明 Javadoc 注释,比如:`canonicalName` 属性,如果不加注释的话,可能后续的维护者难以理解其真正含义。 478 | - 如果一个方法重写了超类中的方法,那么 Javadoc 也是可选的。 479 | 480 | ### 7.4 JDK 源码中的 Javadoc 示例 481 | 482 | 下面是 JDK 源码中 `Callable` 接口的 Javadoc 示例,大家也可以参考借鉴下: 483 | 484 | ```java 485 | /** 486 | * The {@code String} class represents character strings. All 487 | * string literals in Java programs, such as {@code "abc"}, are 488 | * implemented as instances of this class. 489 | *

490 | * Strings are constant; their values cannot be changed after they 491 | * are created. String buffers support mutable strings. 492 | * Because String objects are immutable they can be shared. For example: 493 | *

494 |  *     String str = "abc";
495 |  * 

496 | * is equivalent to: 497 | *

498 |  *     char data[] = {'a', 'b', 'c'};
499 |  *     String str = new String(data);
500 |  * 

501 | * Here are some more examples of how strings can be used: 502 | *

503 |  *     System.out.println("abc");
504 |  *     String cde = "cde";
505 |  *     System.out.println("abc" + cde);
506 |  *     String c = "abc".substring(2,3);
507 |  *     String d = cde.substring(1, 2);
508 |  * 
509 | *

510 | * The class {@code String} includes methods for examining 511 | * individual characters of the sequence, for comparing strings, for 512 | * searching strings, for extracting substrings, and for creating a 513 | * copy of a string with all characters translated to uppercase or to 514 | * lowercase. Case mapping is based on the Unicode Standard version 515 | * specified by the {@link java.lang.Character Character} class. 516 | *

517 | * The Java language provides special support for the string 518 | * concatenation operator ( + ), and for conversion of 519 | * other objects to strings. String concatenation is implemented 520 | * through the {@code StringBuilder}(or {@code StringBuffer}) 521 | * class and its {@code append} method. 522 | * String conversions are implemented through the method 523 | * {@code toString}, defined by {@code Object} and 524 | * inherited by all classes in Java. For additional information on 525 | * string concatenation and conversion, see Gosling, Joy, and Steele, 526 | * The Java Language Specification. 527 | * 528 | *

Unless otherwise noted, passing a null argument to a constructor 529 | * or method in this class will cause a {@link NullPointerException} to be 530 | * thrown. 531 | * 532 | *

A {@code String} represents a string in the UTF-16 format 533 | * in which supplementary characters are represented by surrogate 534 | * pairs (see the section Unicode 535 | * Character Representations in the {@code Character} class for 536 | * more information). 537 | * Index values refer to {@code char} code units, so a supplementary 538 | * character uses two positions in a {@code String}. 539 | *

The {@code String} class provides methods for dealing with 540 | * Unicode code points (i.e., characters), in addition to those for 541 | * dealing with Unicode code units (i.e., {@code char} values). 542 | * 543 | * @author Lee Boynton 544 | * @author Arthur van Hoff 545 | * @author Martin Buchholz 546 | * @author Ulf Zibis 547 | * @see java.lang.Object#toString() 548 | * @see java.lang.StringBuffer 549 | * @see java.lang.StringBuilder 550 | * @see java.nio.charset.Charset 551 | * @since JDK1.0 552 | */ 553 | public final class String 554 | implements java.io.Serializable, Comparable, CharSequence { 555 | 556 | ... 557 | } 558 | 559 | ``` 560 | 561 | ## 8 相对于 Google 风格指南的修改点 :id=modification-point 562 | 563 | 本文档相对于 Google 的 Java 编程风格文档而言,修改了部分规范,增加了一些更加确定性的规则说明,这样能最大程度上的让代码风格统一、易读。且本文档的语言描述会更加的精简。 564 | 565 | ### 8.1 [新增] 类成员的排列顺序约定 566 | 567 | > **新增原因**:相比 Google 风格指南文档中“模糊而又正确”的说法,采用了更为“确定性、可明确实施的”约定。 568 | 569 | ### 8.2 [新增] 不使用行尾注释,建议在代码行或逻辑行之上做单行注释即可 570 | 571 | > **新增原因**:不容易首先阅读到,且行尾注释会占列长度,且容易导致超过列长度限制,后期维护注释麻烦。 572 | 573 | ### 8.3 [新增] 命名规则建议 574 | 575 | 抽象类命名使用 `Abstract` 开头,枚举类后建议以 `Enum` 或 `Type` 结尾,枚举实例值的单词之间用下划线(`_`)来分割。异常类命名使用`Exception`结尾;测试类命名以它要测试的类的名称开始,以 `Test` 结尾。接口名**不建议**使用 `I` 作为前缀,跟 JDK 学习,应该考虑使用名词或形容词。 576 | 577 | > **新增原因**:对类更易于识别。 578 | 579 | ### 8.4 [新增] 命名选择使用英文单词还是中文词语 580 | 581 | > **新增原因**:本人及工作的团队也都是中国人,在编程领域的命名通常使用英文单词即可。但如果涉及到专业领域的词汇,翻译不出简单而又准确的英文时,需要考察实际情况选择使用中文拼音或中文简拼来命名,且附上准确的 Javadoc 注释,不要使用晦涩难懂或存在严重歧义的英文单词。 582 | 583 | ### 8.5 [新增] 新增了换行时,末尾以空行结尾的建议 584 | 585 | > **新增原因**:这只是一个建议的写法,非强制,这样写也是由于“历史原因”引起的,我这里的目的也是跟 Java 源码的风格保持一致。 586 | 587 | ### 8.6 [新增] 新增了 `@author`、`@since`、`@see` 等 Javadoc 标签 588 | 589 | > **新增原因**:在写 Javadoc 时这些注解也是十分有用的,便于大家写出更好的 Javadoc 注释代码。 590 | 591 | ### 8.7 [修改] 如果空语句块,也需要遵守 `K&R` 风格,且增加了语句为空的理由注释 592 | 593 | > **修改原因**:更加明确的规范,利于大家写出“更加一致”的代码,且有助于后来人理解为什么要保持语句块是空的。 594 | 595 | ### 8.8 [修改] 缩进空格数改为了 4 个空格 596 | 597 | > **修改原因**:根据我实际的编程经验,`2` 个空格的代码缩进,在当前大屏幕流行的时代,会显得十分拥挤(挤成一坨),反而使得代码`臃肿`不够美观。所以,我这里建议使用`4`个空格来缩进,会使得更加美观、协调,而且能侧面督促开发人员减少代码的嵌套层数。 598 | 599 | ### 8.9 [修改] 列长度限制改为了 120 个字符 600 | 601 | > **修改原因**:Java 相比其他编程语言而言,类和方法的命名都要“长”很多,这样所占的列数就更多,如果列限制仅设置为 `100` 的话,代码被折行的几率会更大。且在当前大屏幕流行的时代,屏幕右边会空出一大部分空间并没有被代码真正的填充,简直就是浪费,而且使得阅读代码时,视线会重复“跳行”。 602 | 603 | ### 8.10 [修改] 枚举实例之间需要换行,且附加文档注释 604 | 605 | > **修改原因**:枚举本质上也是类,所以,类中的很多规则也适用于枚举。由于枚举实例都是 `public static final` 的,所以,也必然需要添加 Javadoc 注释,所以,实例与实例之间需要使用换行来分割。 606 | 607 | ### 8.11 [修改] 注解是否换行 608 | 609 | 注解应用到类、属性、构造方法、方法上时,应紧接 Javadoc 之后,且独立成行。如果注解应用在参数或者局部变量上时,建议与他们写到一行。 610 | 611 | > **修改原因**:易于识别和阅读。 612 | 613 | ### 8.12 [修改] 领域模型类的命名可以使用连续大写 614 | 615 | 类命名如果是以 `DO`、`DTO`、`BO` 等结尾的领域模型类时,可以考虑使用连续大写。 616 | 617 | > **修改原因**:这里修改的主要原因是为了“**兼容**”阿里规约,但我本人建议少使用这些对象,不仅刻板,而且会造成大量的重复代码、属性来回的设值或复制等,后续维护也要同时维护多个实体。程序员虽然遵循规范,但也不应该是机械的,应该视具体的业务场景建立对应的相关实体类和该类的专属行为。所以,我的个人建议是除了数据库层的实体类,其他实体类应该使用“充血模型”,这样更加面向对象编程。因此考验程序员的难点就成了“如何设计充血模型”,或者说“如何从复杂的业务中分离出恰到好处的逻辑行为放到 `VO` 之类的方法中”。但如果你的团队程序员以初级工程师为主,且业务都是 `CRUD` 的话,可以规范使用“贫血模型”。 618 | 619 | ### 8.13 [修改]泛型名都以单个大写字母开头 620 | 621 | > **修改原因**:跟 JDK 中的命名风格保持一致。 622 | -------------------------------------------------------------------------------- /docs/guide/google-java-style-guide-cn.md: -------------------------------------------------------------------------------- 1 | # Google Java 编程风格指南 2 | 3 | ## 1 介绍 4 | 5 | 这份文档是 Google Java 编程风格规范的**完整**定义。当且仅当 Java 源文件符合此文档中的规则时,我们才认为它符合 Google 的 Java 编程风格。 6 | 7 | 与其它的编程风格指南一样,这些问题不仅涵盖编码格式方面的美学问题,而且还涵盖了其他方面的约定和编码标准。然而,本文档主要侧重于我们普遍遵循的**严格规则**,并避免给出无法明确执行的建议(无论是通过人工还是通过工具)。 8 | 9 | ### 1.1 术语说明 10 | 11 | 在本文档中,除非特殊说明: 12 | 13 | 1. 术语 `class` 表示“普通”类,枚举类,接口或注解(`@interface`)。 14 | 2. 术语 `member`(在类中)表示嵌套的类、属性、方法或者构造方法,也就是一个类中的所有顶级内容,初始值和注释除外。 15 | 3. 术语 `comment` 只用来表示实现的注释(`implementation comments`),我们不使用文档注释(`documentation comments`)一词,而是用`Javadoc`。 16 | 17 | 其他术语的说明,将偶尔在文档中的特定地方单独说明。 18 | 19 | ### 1.2 指南 20 | 21 | 本文档中的示例代码并**不作为规范**。也就是说,虽然示例代码是遵循 Google 编程风格的,但并不意味着这是表示这些代码的唯一方式。示例中的格式选择不应该被强制定为规则。 22 | 23 | ## 2 源文件基础 24 | 25 | ### 2.1 文件名 26 | 27 | 源文件名由最顶层的、大小写敏感的类名(只有[一个](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s3.4.1-one-top-level-class))来命名,文件扩展名为 `.java`。 28 | 29 | ### 2.2 文件编码:UTF-8 30 | 31 | 源文件使用 **UTF-8** 编码。 32 | 33 | ### 2.3 特殊字符 34 | 35 | #### 2.3.1 空格字符 36 | 37 | 除了换行符外,**ASCII 水平空格字符(`0x20`)**是源码文件中唯一支持的空格字符。这意味着: 38 | 39 | 1. 所有其他空白字符将都会被转义。 40 | 2. Tab 制表符不用于缩进。 41 | 42 | #### 2.3.2 特殊转义序列 43 | 44 | 对于具有[特殊转义序列](http://docs.oracle.com/javase/tutorial/java/data/characters.html)(例如:`\b`, `\t`, `\n`, `\f`, `\r`, `\"`, `\'`, `\\`等)的字符,都采用这种转义字符的方式表示,而不采用对应字符的八进制数(如:`\012`)或 Unicode (如:`\u000a`)来表示。 45 | 46 | #### 2.3.3 非 ASCII 字符 47 | 48 | 对于其余的非 ASCII 字符,就直接使用 Unicode 字符即可(如:`∞`),或者使用等效的 Unicode 转义符(如:`\u221e`)。尽管强烈建议不要使用 Unicode 字符来表示字符串,但选择的核心理由是哪种代码更让人**易于阅读和理解**。 49 | 50 | > **提示**:在使用 Unicode 转义符时,或者甚至是有时直接使用 Unicode 字符的时候,建议多添加一些解释性的注释说明。 51 | 52 | 示例: 53 | 54 | | 示例 | 结论 | 55 | | ------------ | ------------ | 56 | | String unitAbbrev = "μs"; | 最佳:即使没有注释也非常清晰。 | 57 | | String unitAbbrev = "\u03bcs"; // "μs" | 允许,但没有理由要这样做。 | 58 | | String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" | 允许,但这样做显得笨拙还容易出错。 | 59 | | String unitAbbrev = "\u03bcs"; | 很糟:读者根本看不出这是什么。 | 60 | | return '\ufeff' + content; // byte order mark | 很好:对于非打印字符,使用转义,并在必要时写上注释。 | 61 | 62 | > **提示**:不要因为担心某些程序可能无法正确处理非 ASCII 字符而降低了代码的可读性。如果真的发生这种情况,程序就会**阻断**,必须对其进行**修复**。 63 | 64 | ## 3 源文件结构 65 | 66 | 源文件按**从上到下的顺序**,由以下几部分组成: 67 | 68 | 1. 许可证 (`License`)或版权信息(`copyright`)(如果有) 69 | 2. 包(`package`)语句 70 | 3. 包导入(`import`)语句 71 | 4. 类(`class`)声明 72 | 73 | > **注意**:以上每个部分之间应该只有**一个空行**作为分隔。 74 | 75 | ### 3.1 许可证或版权信息(如果有) 76 | 77 | 如果一个文件中包含许可证或版权信息,那么它应该在文件最前面。 78 | 79 | ### 3.2 package 语句 80 | 81 | 包(`package`)语句不换行,列限制(4.4 节,[列限制](#))不适用于 `package` 语句。(即 `package` 语句独立成行) 82 | 83 | ### 3.3 import 语句 84 | 85 | #### 3.3.1 import 不使用通配符 86 | 87 | 包导入(`import`)语句中**都不使用通配符**),不管是否是静态导入(`static import`)。 88 | 89 | #### 3.3.2 import 不换行 90 | 91 | 包导入(`import`)语句不换行,列限制(4.4 节,[列限制](#))不适用于 `import` 语句。(即每个 `import` 语句独立成行) 92 | 93 | #### 3.3.3 顺序和间距 94 | 95 | 包导入(`import`)语句顺序如下: 96 | 97 | 1. 所有静态导入(`static import`)都在一个块中。 98 | 2. 所有非静态导入都在一个块中。 99 | 100 | 如果同时具有静态和非静态导入,则使用**一个空行**将两块分开。每个块的若干导入语句之间不空行。 101 | 102 | 在每个块中,导入的名称均按 ASCII 顺序排序。(**注意**:这与按 ASCII 排序的 import 语句不同,因为 `.` 在 `;` 之前排序。) 103 | 104 | #### 3.3.4 静态内部类不用静态导入 105 | 106 | 静态内部类中不用静态导入(`static import`)。它们使用普通方式的导入(`import`)语句。 107 | 108 | ### 3.4 类声明 109 | 110 | #### 3.4.1 仅有一个顶级类声明 111 | 112 | 每个源文件中只能有一个顶级类(`class`)声明。 113 | 114 | #### 3.4.2 类成员顺序 115 | 116 | 类成员的顺序对代码的易读性有很大的影响,但是没有一个统一正确的标准。不同的类可能有不同的排序方式。 117 | 118 | 最重要的一点,**类中的所有成员都应该以某种逻辑去排序,维护者要能够解释这种排序逻辑**。比如,新的方法不能总是习惯性地添加到类的结尾,因为这样就是按创建的时间顺序而非某种逻辑来排序了。 119 | 120 | ##### 3.4.2.1 重载:永不分离 121 | 122 | 当一个类中有多个构造函数或者多个同名方法时,这些方法应该按顺序排列在一起,中间不要插入其它方法(甚至是私有成员)。 123 | 124 | ## 4 格式 125 | 126 | **术语说明**:块状结构(`block-­like construct`)指的是以类、方法或构造函数为主体。需要注意的是,根据第 4.8.3.1 节的[数组初始化](#)中的初始值可被选择性地视为块状结构。 127 | 128 | ### 4.1 大括号 129 | 130 | #### 4.1.1 使用大括号(即使是可选的) 131 | 132 | 大括号一般用在 `if`, `else`, `for`, `do` 和 `while` 等语句,即使只有一条语句(或者内容是空)的时候,也应该把大括号写上。 133 | 134 | #### 4.1.2 非空语句块采用 K&R 风格 135 | 136 | 对于非空语句块,大括号遵循 Kernighan 和 Ritchie 风格(["Egyptian brackets"](http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html)): 137 | 138 | - 左大括号前不换行 139 | - 左大括号后换行 140 | - 右大括号前换行 141 | - 如果右大括号结束是一个语句块或者方法体、构造函数体或者有命名的类体,则需要换行。当右括号后面接 `else` 或逗号(`,`)时,不换行。 142 | 143 | 示例: 144 | 145 | ```java 146 | return () -> { 147 | while (condition()) { 148 | method(); 149 | } 150 | }; 151 | 152 | return new MyClass() { 153 | @Override public void method() { 154 | if (condition()) { 155 | try { 156 | something(); 157 | } catch (ProblemException e) { 158 | recover(); 159 | } 160 | } else if (otherCondition()) { 161 | somethingElse(); 162 | } else { 163 | lastThing(); 164 | } 165 | } 166 | }; 167 | ``` 168 | 169 | 一些例外的情况,将在 4.8.1 节[枚举类](#)中介绍。 170 | 171 | #### 4.1.3 空语句块:使代码更简洁 172 | 173 | 一个空的语句块或者空的构造方法,可以采用 K&R 风格(如 [4.1.2 节](#4.1.2)中所述)。也可以直接闭合(`{}`),中间不需要换行、空格或其他字符。但是,它与其他几个语句块联合组成语句块时,则需要换行。(例如:`if/else` 或者 `try/catch/finally`)。 174 | 175 | 示例: 176 | 177 | ```java 178 | // 这是可接受的 179 | void doNothing() {} 180 | 181 | // 这也同样是可接受的 182 | void doNothingElse() { 183 | } 184 | ``` 185 | 186 | ```java 187 | // 这是不可接受的:多块语句中没有简洁的空语句块. 188 | try { 189 | doSomething(); 190 | } catch (Exception e) {} 191 | ``` 192 | 193 | ### 4.2块缩进:2个空格 194 | 195 | 每当一个新的语句块产生,缩进就增加两个空格。当这个语句块结束时,缩进恢复到上一层级的缩进级别。此缩进要求对整个语句块中的代码和注释都适用。(请参见 4.1.2 节,[非空语句块采用 K&R 风格](#)) 196 | 197 | > **注意**:根据实际的编程经验,`2`个空格缩进的代码在当前大屏的计算机上会显得十分拥挤,反而使得代码`臃肿`不够美观。所以,我这里建议使用`4`个空格来缩进,会使得更加美观,而且能侧面督促开发人员减少代码的嵌套层数。 198 | 199 | ### 4.3 一条语句占一行 200 | 201 | 每条语句结束都需要换行。 202 | 203 | ### 4.4 列长度限制:100 204 | 205 | Java 代码的列长度限制为 `100` 个字符。“字符”表示任何 Unicode 代码点。除非另有说明,否则超出此限制的任何行都必须进行换行,在 4.5 节会有“[换行](#)”的介绍。 206 | 207 | > 每个 Unicode 代码点都算作一个字符,即使其显示宽度更大或更小。例如,如果使用[全角字符](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms),则可以选择在此规则严格要求的位置之前换行。 208 | 209 | 例外情况: 210 | 211 | 1. 不可能满足列长度限制的行(例如,Javadoc 中的一个长 URL,或是一个长的 JSNI 方法引用)。 212 | 2. `package` 和 `import` 语句(见 3.2 节和 3.3 节)。 213 | 3. 注释中的命令行,它们可能用于剪切粘贴到 shell 中。 214 | 215 | ### 4.5 换行 216 | 217 | **术语说明**:将原本合法占用一行的代码分成多行,则该操作称之为“换行”(`line­-wrapping`)。 218 | 219 | 我们并没有全面,确定性的准则来决定在每一种情况下如何断行。通常,可以有几种有效的方式对同一段代码进行换行。 220 | 221 | > **注**: 虽然换行的典型原因是避免超出列限制,但实际上,满足列限制的代码也可以由作者自行决定是否换行。 222 | 223 | > **提示**:提取方法或局部变量也许可以解决问题,而不需要进行换行。 224 | 225 | #### 4.5.1 在哪里换行 226 | 227 | 换行的主要原则是:**选择在更高级的语法逻辑处换行**。包括: 228 | 229 | 1. 当在一个非赋值运算的语句换行时,在运算符号之前换行。(这与 Google 的 C++ 规范和 JavaScrip 规范等其他规范不同)。 230 | - 下面`类似运算符`的情况也适用: 231 | - 点(`.`)操作符 232 | - 方法引用中双冒号(`::`)操作符 233 | - 泛型符号(``) 234 | - `catch` 块中的管道符号(`catch (FooException | BarException e)`) 235 | 2. 当要在赋值运算符语句处换行时,一般在赋值符号之后换行。不过,不管选哪一种方式都是可以接受的。 236 | - 这也适用于增强 for 循环(`foreach`)语句中的冒号(`:`)。 237 | 3. 方法名或构造函数名与仍然左括号(`(`)留在同一行。 238 | 4. 逗号(`,`)与其前面的内容留在同一行。 239 | 5. 在 `Lambda` 表达式中的箭头旁边永远不要换行,除非当 `Lambda` 表达式的主体由单个无括号的表达式组成时,可能会在箭头之后换行。示例: 240 | 241 | ```java 242 | MyLambda lambda = 243 | (String label, Long value, Object obj) -> { 244 | ... 245 | }; 246 | 247 | Predicate predicate = str -> 248 | longExpressionInvolving(str); 249 | ``` 250 | 251 | > **注**:换行的主要目标是使代码更清晰易读,而不是书写最少行数的代码。 252 | 253 | #### 4.5.2 换行缩进:至少 +4 个空格 254 | 255 | 自动换行时,第一行后的每一行都至少比第一行多缩进 `4` 个空格。 256 | 257 | 当存在连续自动换行时,缩进可能会多缩进不只 `4` 个空格(语法元素存在多级时)。一般而言,两个连续行要使用相同的缩进,当且仅当它们使用了同级别的语法元素。 258 | 259 | 第 4.6.3 节[水平对齐](#)中指出,不鼓励使用可变数目的空格来对齐前面行的符号。 260 | 261 | ### 4.6 空白 262 | 263 | #### 4.6.1 垂直空白 264 | 265 | 以下情况总要使用一个空行分割: 266 | 267 | 1. 类成员之间需要单个空行隔开:例如:字段,构造函数,方法,内部类,静态初始化块,实例初始化块。 268 | - **例外情况**:两个连续属性之间的空行是可选的,根据需要使用空行来创建字段间的逻辑分组。 269 | - **例外情况**:第 [4.8.1 节](#)介绍了枚举常量之间的空白行。 270 | 2. 根据本文档其他章节的要求(如第 3 节,[源文件结构](#)和第3.3节,[import 语句](#))。 271 | 272 | 一个空行也可以出现在任何提高可读性的地方,例如在语句之间将代码组织成逻辑子部分。在类的第一个成员之前或最后一个成员之后,使用空行(可选)。 273 | 274 | 不需要使用多个连续的空行(不鼓励)。 275 | 276 | #### 4.6.2 水平空白 277 | 278 | 除了语法、其他规则、词语分隔、注释和 Javadoc 外,水平的 ASCII 空格只在以下情况出现: 279 | 280 | 1. 所有保留的关键字与紧接它之后同一行的左小括号(`(`)之间需要用空格隔开,例如:`if`, `for` `catch`。 281 | 2. 所有保留的关键字与在它之前的右大括号(`}`)之间需要空格隔开,例如:`else`、`catch`。 282 | 3. 在左大括号之前都需要空格隔开。 283 | - **例外情况**:`@SomeAnnotation({a, b})`(不使用空格)。 284 | - **例外情况**:`String[][] x = {{"foo"}};`(第二个 `{` 之前不使用空格)。 285 | 4. 所有的二元和三元运算符的两边,都需要使用空格隔开。以下“类似操作符”的情况也适用: 286 | - 连接泛型类型的 `&` 符号:`` 287 | - 处理多个异常 `catch` 中的管道操作符:`catch (FooException | BarException e)` 288 | - 增强 `for` 循环(`foreach`)中的冒号:`:` 289 | - `Lambda` 表达式中的箭头符号(`->`) 290 | 例外情况: 291 | - 方法引用中的双冒号(`::`),写法类似于 `Object::toString` 292 | - 点号操作符(`.`),写法类似于 `object.toString()` 293 | 5. 逗号(`,`)、冒号(`:`)、分号(`;`)和右小括号(`)`)、Lambda箭头符号(`->`)之后,需要空格隔开。 294 | 6. 使用`//`双斜线开始一行注释时,双斜线两边都应该用空格隔开。并且可使用多个空格。(可选的,例如:`a = 0; // 赋值为0`) 295 | 7. 在声明的变量类型和变量名之间需要用空格隔开:`List list` 296 | 8. 初始化一个数组时,大括号内的空格是可选的。 297 | - `new int[] {5, 6}` 和 `new int[] { 5, 6 }` 这两种都是可以的 298 | 9. 在类型注解和 `[]` 或者 `...` 之后使用空格。 299 | 300 | > **注意**:这些规则并不要求或禁止一行的开关或结尾需要额外的空格,只对内部空格做要求。 301 | 302 | ### 4.6.3 水平对齐:不需要 303 | 304 | > **术语说明**:水平对齐,是指通过添加多个空格,使本行的某一符号与上一行的某一符号上下对齐。 305 | 306 | 这种对齐是被允许的,但是不会做强制要求。 307 | 这种对齐是允许的,但**从来不是**谷歌风格所要求的。甚至不需要在已经使用过的地方保持水平对齐。 308 | 309 | 以下是没有水平对齐和做了水平对齐的例子: 310 | 311 | ```java 312 | private int x; // 这种挺好 313 | private Color color; // 同上 314 | 315 | private int x; // 允许,但是未来会继续编辑 316 | private Color color; // 可能会使它对不齐 317 | ``` 318 | 319 | > **提示**:水平对齐可以提高代码的可读性,但是增加了未来维护代码的麻烦。考虑到维护时只需要改变一行代码,之前的对齐可以不需要改动。为了对齐,你更有可能改了一行代码,同时需要更改附近的好几行代码,而这几行代码的改动,可能又会引起一些为了保持对齐的代码改动。那原本这行改动,我们称之为**爆炸半径**。这种改动,在最坏的情况下可能会导致大量的无意义的工作,即使在最好的情况下,也会影响版本历史信息,减慢代码 `review` 的速度,引起更多合并代码的冲突。 320 | 321 | ### 4.7 分组小括号:推荐使用 322 | 323 | 除非作者和审阅人(`reviewer`)都认为去掉小括号也不会使代码被误解,或是去掉小括号能让代码更易于阅读,否则我们不应该去掉小括号。假设读者能记住整个 Java 运算符优先级表,是不合理的。 324 | 325 | ### 4.8 特殊结构 326 | 327 | #### 4.8.1 枚举类 328 | 329 | 枚举常量间用逗号隔开,换行是可选的。而且还允许附加的空行(通常只有一个)。以下是一些可行的示例: 330 | 331 | ```java 332 | private enum Answer { 333 | YES { 334 | @Override public String toString() { 335 | return "yes"; 336 | } 337 | }, 338 | 339 | NO, 340 | MAYBE 341 | } 342 | ``` 343 | 344 | 没有方法和 Javadoc 的枚举类可写成数组初始化的格式: 345 | 346 | ```java 347 | private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS } 348 | ``` 349 | 350 | 由于枚举类也是一个类,因此所有适用于其它类的格式规则也适用于枚举类。 351 | 352 | #### 4.8.2 变量声明 353 | 354 | ##### 4.8.2.1 每次声明一个变量 355 | 356 | 每个变量声明(字段或局部变量)只声明一个变量:不使用诸如 `int a, b;` 之类的声明。 357 | 358 | **例外情况**: `for` 循环的初始化头中可以使用多个变量声明。 359 | 360 | ##### 4.8.2.2 需要时才声明 361 | 362 | 不要在代码块的开头把所有局部变量一次性全部进行声明,而是在第一次需要使用它时才声明,这样能最大程度地减小其作用范围。局部变量在声明时最好就进行初始化,或者声明后尽快进行初始化。 363 | 364 | #### 4.8.3 数组 365 | 366 | ##### 4.8.3.1 数组初始化:可以是块状结构 367 | 368 | 数组初始化可以写成块状结构,例如以下格式的写法都是允许的(): 369 | 370 | ```java 371 | new int[] { new int[] { 372 | 0, 1, 2, 3 0, 373 | } 1, 374 | 2, 375 | new int[] { 3, 376 | 0, 1, } 377 | 2, 3 378 | } new int[] 379 | {0, 1, 2, 3} 380 | ``` 381 | 382 | ##### 4.8.3.2 非 C 风格的数组声明 383 | 384 | 中括号是类型的一部分:`String[] args`, 而非 `String args[]`。 385 | 386 | #### 4.8.4 switch 语句 387 | 388 | **术语说明**:switch 块的大括号内是一个或多个语句组。每个语句组包含一个或多个 `switch` 标签(`case FOO:` 或 `default:`),后面跟着一条或多条语句(对于最后一个语句组,则为零个或多个语句)。 389 | 390 | ##### 4.8.4.1 缩进 391 | 392 | 和其他语句块一样,switch 大括号之后缩进两个字符。 393 | 394 | 每个 switch 标签之后,有一个换行符,并按照大括号相同的处理方式缩进两个字符。在标签结束后,恢复到之前的缩进,类似大括号的结束符。 395 | 396 | ##### 4.8.4.2 直落(fall through):注释 397 | 398 | 在 switch 块内,每个语句组要么通过 `break`、`continue`、`return` 或 `throw 异常`来终止,要么通过一条注释来说明程序将继续执行到下一个语句组,任何能表达这个意思的注释都是可以的(典型的是用 `// fall through`)。在 switch 块的最后一个语句组中不需要此特殊的注释。例如: 399 | 400 | ```java 401 | switch (input) { 402 | case 1: 403 | case 2: 404 | prepareOneOrTwo(); 405 | // fall through 406 | case 3: 407 | handleOneTwoOrThree(); 408 | break; 409 | default: 410 | handleLargeNumber(input); 411 | } 412 | ``` 413 | 414 | > **注意**:在 `case 1` 之后仅在语句组的末尾不需要该注释。 415 | 416 | 每个 switch 语句中,都需要显式声明 `default` 语句,即使没有任何代码。 417 | 418 | > **注意**:枚举类型的 switch 语句可以省略`default`语句组,如果它包含覆盖该类型的所有可能值的显式情况。这使得IDE或其他静态分析工具能够在丢失任何情况时发出警告。 419 | 420 | **例外**:如果枚举类型的 switch 语句包含包含该类型所有可能值的情况,则可以省略 `default` 语句组。这使得 IDE 或其他静态分析工具能够在丢失任何情况时发出警告。 421 | 422 | #### 4.8.5 注解 423 | 424 | 注解应用到类、方法或者构造方法上时,应紧接 Javadoc 之后。每行只能有一个注解。注解所在行不受列长度限制(4.5 节,[换行](#)),也不需要增加缩进。例如: 425 | 426 | ```java 427 | @Override 428 | @Nullable 429 | public String getNameIfPresent() { ... } 430 | ``` 431 | 432 | **例外**:如果注解只有一个,并且不带参数。则它可以和类或方法名放在同一行。例如: 433 | 434 | ```java 435 | @Override public int hashCode() { ... } 436 | ``` 437 | 438 | 当注解应用到成员变量时,也是紧接 Javadoc 之后。不同的是,多个注解可以放在同一行。例如: 439 | 440 | ```java 441 | @Partial @Mock DataLoader loader; 442 | ``` 443 | 444 | 对于参数或者局部变量使用注解的情况,没有特定的规范。 445 | 446 | #### 4.8.6 注释 447 | 448 | 本节介绍注释的使用。Javadoc 在第 7 节 [Javadoc](#) 中单独介绍。 449 | 450 | 任何换行符之前都可以带有任意空格后再跟注释。这样的注释使该行成为非空白行。 451 | 452 | ##### 4.8.6.1 块注释风格 453 | 454 | 注释的缩进与它所注释的代码缩进相同。可以采用 `/* ... */` 风格,也可以用 `// ...` 风格。当使用 `/* ... */` 进行多行注释时,每一行都应该以 `*` 开始,并且 `*` 应该上下对齐。 455 | 456 | ```java 457 | /* 458 | * This is // And so /* Or you can 459 | * okay. // is this. * even do this. */ 460 | */ 461 | ``` 462 | 463 | 注释不包含在用星号(`*`)或其他字符绘制的框中。 464 | 465 | > **提示**:在编写多行注释时,如果希望自动代码格式化的程序在必要时重新进行换行,请使用 `/* ... */` 的风格(段落样式)。大多数格式化程序不会在 `// ...` 风格的注释块中重新换行。 466 | 467 | #### 4.8.7 修饰符 468 | 469 | 类和成员变量的修饰符,按 `Java Lauguage Specification` 中介绍的先后顺序排序。具体是: 470 | 471 | ```java 472 | public protected private abstract default static final transient volatile synchronized native strictfp 473 | ``` 474 | 475 | #### 4.8.8 数字字面量 476 | 477 | 长整型(`long`)的数字字面量使用大写的 `L` 作为后缀,不得使用小写(避免与数字 `1` 混淆)。例如:使用 `3000000000L`,而不是 `3000000000l`。 478 | 479 | ## 5 命名 480 | 481 | ### 5.1 对所有标识符都通用的规则 482 | 483 | 标识符只能使用 ASCII 字母和数字,并且在以下少数情况下才使用下划线。因此每个有效的标识符名称都能使用正则表达式 `\w+` 来匹配。 484 | 485 | 在 Google 编程风格中不使用特殊的前缀或后缀,如`name_`, `mName`, `s_name` 或 `kName`。 486 | 487 | ### 5.2 标识符类型的规则 488 | 489 | #### 5.2.1 包名 490 | 491 | 包名全部小写,连续的单词只是简单地连接起来,不使用下划线。例如:使用 `com.example.deepspace`,而不是 `com.example.deepSpace` 或者 `com.example.deep_space`。 492 | 493 | #### 5.2.2 类名 494 | 495 | 类名都以大驼峰([UpperCamelCase](#))风格编写。 496 | 497 | 类名通常是名词或名词短语。例如:`Character` 或者 `ImmutableList`。接口名称也可以是名词或名词短语(例如:`List`),但有时可能是形容词或形容词短语(例如:`Readable`)。 498 | 499 | 注解的命名还没有特定的规则,甚至没有完善的约定。 500 | 501 | 测试类的命名以它要测试的类的名称开始,以 `Test` 结束。例如:`HashTest` 或 `HashIntegrationTest`。 502 | 503 | #### 5.2.3 方法名 504 | 505 | 方法名都以小驼峰([lowerCamelCase](#))风格编写。 506 | 507 | 方法名通常是动词或动词短语。例如:`sendMessage` 或者 `stop`。 508 | 509 | 下划线可能出现在 JUnit 测试方法名称中,用以分隔名称的逻辑组成,每个组成部分均用 [lowerCamelCase](#) 编写。一个典型的模式是:`_`,例如:`Pop_emptyStack`。并不存在唯一正确的方式来命名测试方法。 510 | 511 | #### 5.2.4 常量名 512 | 513 | 常量名的命名模式为 `CONSTANT_CASE`,字母全部大写,使用下划线来分隔单词。那到底什么算是一个常量呢? 514 | 515 | 每个常量都是一个静态 `final` 字段,其内容是不可变的,且没有可检测的副作用。这包括原始类型、字符串、不可变类型和不可变类型的不可变集合。如果任何一个实例的观测状态是可变的,则它肯定不会是一个常量。不可变对象不一定是常量。例如: 516 | 517 | ```java 518 | // 下面是常量. 519 | static final int NUMBER = 5; 520 | static final ImmutableList NAMES = ImmutableList.of("Ed", "Ann"); 521 | static final ImmutableMap AGES = ImmutableMap.of("Ed", 35, "Ann", 32); 522 | static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable 523 | static final SomeMutableType[] EMPTY_ARRAY = {}; 524 | enum SomeEnum { ENUM_CONSTANT } 525 | 526 | // 下面的情况不是常量. 527 | static String nonFinal = "non-final"; 528 | final String nonStatic = "non-static"; 529 | static final Set mutableCollection = new HashSet(); 530 | static final ImmutableSet mutableElements = ImmutableSet.of(mutable); 531 | static final ImmutableMap mutableValues = 532 | ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2); 533 | static final Logger logger = Logger.getLogger(MyClass.getName()); 534 | static final String[] nonEmptyArray = {"these", "can", "change"}; 535 | ``` 536 | 537 | 这些常量的名字通常是名词或名词短语。 538 | 539 | #### 5.2.5 非常量字段名 540 | 541 | 非常量字段名以小驼峰(`lowerCamelCase`)风格命名。 542 | 543 | 这些名字通常是名词或名词短语。例如:`computedValues` 或者 `index`。 544 | 545 | #### 5.2.6 参数名 546 | 547 | 参数名以小驼峰(`lowerCamelCase`)风格命名。 548 | 549 | 在公共方法中应该避免用单个字符来对参数进行命名。 550 | 551 | #### 5.2.7 局部变量名 552 | 553 | 局部变量名以小驼峰(`lowerCamelCase`)风格命名。 554 | 555 | 即使局部变量是 `final` 和不可改变的,也不应该把它示为常量,当然也就不能用常量的规则去命名它。 556 | 557 | #### 5.2.8 泛型名 558 | 559 | 泛型可以用以下两种风格之一进行命名: 560 | 561 | - 单个的大写字母,后面可以视具体情况跟一个数字(如:`E`, `T`, `X`, `T2`)。 562 | - 以类命名方式(5.2.2 节,[类名](#)),后面加个大写的 `T`(如:`RequestT`, `FooBarT`)。 563 | 564 | ### 5.3 驼峰命名法(CamelCase)的定义 565 | 566 | **驼峰式命名法**分大驼峰式命名法(`UpperCamelCase`)和小驼峰式命名法(`lowerCamelCase`)。有时,我们有多种合理的方式将一个英语词组转换成驼峰形式,如缩略语或不寻常的结构,例如:`IPv6` 或 `iOS`。Google 风格指定了以下的(几乎)确定性的转换方案。 567 | 568 | 名字从散文形式(`prose form`)开始: 569 | 570 | 1. 把短语转换为纯 ASCII 码,并且移除任何单引号。例如:`Müller’s algorithm` 将变成 `Muellers algorithm`。 571 | 2. 把这个结果切分成单词,在空格或其它标点符号(通常是连字符)处分割开。 572 | - **推荐**:如果某个单词已经有了常用的驼峰表示形式,按它的组成将它分割开(如`AdWords`将分割成`ad words`)。需要注意的是 `iOS` 并不是一个真正的驼峰表示形式,因此该推荐对它并不适用。 573 | 3. 现在将所有字母都小写(包括缩写),然后将单词的第一个字母大写: 574 | - 每个单词的第一个字母都大写,来得到大驼峰式命名。 575 | - 除了第一个单词,每个单词的第一个字母都大写,来得到小驼峰式命名。 576 | 4. 最后将所有的单词连接起来得到一个标识符。 577 | 578 | 请注意,几乎完全忽略了原始单词的大小写。示例: 579 | 580 | | 散文形式 | 正确 | 不正确 | 581 | | ------------ | ------------ | ------------ | 582 | | "XML HTTP request" | XmlHttpRequest | XMLHTTPRequest | 583 | | "new customer ID" | newCustomerId | newCustomerID | 584 | | "inner stopwatch" | innerStopwatch | innerStopWatch | 585 | | "supports IPv6 on iOS?" | supportsIpv6OnIos | supportsIPv6OnIOS | 586 | | "YouTube importer" | YouTubeImporter YoutubeImporter* | 无 | 587 | 588 | 加 `*` 号处表示可以接受,但不推荐。 589 | 590 | > **注意**:在英语中,某些带有连字符的单词形式不唯一。例如:`nonempty` 和 `non-empty` 都是正确的,因此方法名`checkNonempty`和`checkNonEmpty`也都是正确的。 591 | 592 | ## 6 编程实践 593 | 594 | ### 6.1 总是使用 @Override 注解 595 | 596 | 只要是合法的方法,就要加上 `@Override` 注解,这包括重写超类方法的类方法,实现接口方法的类方法以及重新指定父类接口方法的接口方法。 597 | 598 | **例外**:如果父方法为 `@Deprecated` 时,可以省略 `@Override`。 599 | 600 | ### 6.2 不能忽视捕获的异常 601 | 602 | 除了下面的例子,对捕获的异常不做任何响应是极少的。(典型的响应方式是打印日志,或者如果它被认为是不可能的,则把它当作一个 `AssertionError` 重新抛出。) 603 | 604 | 如果它确实是不需要在 `catch` 块中做任何响应,需要做注释加以说明。 605 | 606 | ```java 607 | return handleTextResponse(response); 608 | try { 609 | int i = Integer.parseInt(response); 610 | return handleNumericResponse(i); 611 | } catch (NumberFormatException ok) { 612 | // 它不是一个数字,不过没关系,继续后续操作 613 | } 614 | return handleTextResponse(response); 615 | ``` 616 | 617 | **例外**:在测试中,如果一个捕获的异常被命名为 `expected`,则它可以被不加注释地忽略。下面是一种非常常见的情形,用以确保所测试的方法会抛出一个期望中的异常, 因此在这里就没有必要加注释。 618 | 619 | ```java 620 | try { 621 | emptyStack.pop(); 622 | fail(); 623 | } catch (NoSuchElementException expected) { 624 | } 625 | ``` 626 | 627 | ### 6.3 使用类来调用静态成员 628 | 629 | 使用类名调用静态的类成员,而不是具体某个对象或表达式。 630 | 631 | ```java 632 | Foo aFoo = ...; 633 | Foo.aStaticMethod(); // good 634 | aFoo.aStaticMethod(); // bad 635 | somethingThatYieldsAFoo().aStaticMethod(); // very bad 636 | ``` 637 | 638 | ### 6.4 禁用 Finalizers 639 | 640 | 极少会去重写 `Object.finalize`。 641 | 642 | > **提示**:不要这么做。如果你非要使用它,请先仔细阅读和理解 [Effective Java](http://books.google.com/books?isbn=8131726592) 第 7 条:“Avoid Finalizers”,然后不要使用它。 643 | 644 | ## 7 Javadoc 645 | 646 | ### 7.1 格式 647 | 648 | #### 7.1.1 一般形式 649 | 650 | Javadoc 块的基本格式如下所示: 651 | 652 | ```java 653 | /** 654 | * Multiple lines of Javadoc text are written here, 655 | * wrapped normally... 656 | */ 657 | public int method(String p1) { ... } 658 | ``` 659 | 660 | 或者是以下单行形式: 661 | 662 | ```java 663 | /** 一小段的 Javadoc. */ 664 | ``` 665 | 666 | 基本格式总是可以接受的。当整个 Javadoc 块可以放在一行时(包括注释标签),就可以使用单行形式。请注意,这仅适用于没有 `@return` 等块标记的情况。 667 | 668 | #### 7.1.2 段落 669 | 670 | 空行是只包含最左侧星号(`*`)的空行会出现在段落之间和 Javadoc 注解标记(`@XXX`)之前(如果有的话)。除了第一个段落,每个段落第一个单词前都有标签`

`,并且它和第一个单词间没有空格。 671 | 672 | #### 7.1.3 Javadoc 标记 673 | 674 | 标准的 Javadoc 注解标记按以下顺序出现:`@param`, `@return`, `@throws`, `@deprecated`, 前面这 4 种标记如果出现,描述都不能为空。当描述无法在一行中容纳,连续行需要至少在 `@` 符号的位置处缩进 `4` 个空格。 675 | 676 | #### 7.2 摘要片段 677 | 678 | 每个 Javadoc 都以一个简短的**摘要片段**开始。这个片段是非常重要的,它是文本在某些上下文(如类和方法索引)中出现的唯一部分。 679 | 680 | 这只是一个小片段,可以是一个名词短语或动词短语,但不是一个完整的句子。它不会以 `A {@code Foo} is a...` 或者 `This method returns...` 开头, 它也不会是一个完整的祈使句,如 `Save the record.`。但是,由于开头大写且被加了标点符号,它看起来就像是个完整的句子。 681 | 682 | > **提示**:一个常见的错误是把简单的 Javadoc 写成 `/** @return the customer ID */`,这是不正确的。它应该写成 `/** Returns the customer ID. */`。 683 | 684 | ### 7.3 在哪里使用 Javadoc 685 | 686 | 至少在每个 `public` 类及它的每个 `public` 和 `protected` 成员处使用 Javadoc,下面会提到一些例外情况: 687 | 688 | 额外的 Javadoc 内容也可能存在,如第 7.3.4 节[非必需的Javadoc](#)。 689 | 690 | #### 7.3.1 例外:不言自明的方法 691 | 692 | 对于简单明显的方法如 `getFoo`,Javadoc 是可选的。这种情况下除了写 “`Returns the foo`”,确实也没有什么值得写了。 693 | 694 | > **重要提示**:如果有一些相关信息是需要读者了解的,那么以上的例外不应作为忽视这些信息的理由。例如,对于 `getCanonicalName` 方法,就不应该忽视文档说明,因为读者很可能不知道词语 “`canonical name`” 指的是什么。 695 | 696 | #### 7.3.2 例外:重写 697 | 698 | 如果一个方法重写了超类中的方法,那么 Javadoc 并非必需的。 699 | 700 | #### 7.3.3 可选的 Javadoc 701 | 702 | 对于包外不可见的类和方法,如有需要,也是要使用 Javadoc 的。如果一个注释是用来定义一个类,方法,字段的整体目的或行为,那么这个注释应该写成 Javadoc,这样更统一、更友好。 703 | 704 | #### 7.3.4 不需要 Javadoc 的情况 705 | 706 | 其他类和成员种根据实际是否需要来写 Javadoc。 707 | 708 | 每当将注释用于定义类或成员的总体目的或行为时,该注释就会改为使用 Javadoc 来编写(使用`/**`)。 709 | 710 | 非必需的 Javadoc 并不要求严格遵循第 7.1.2、7.1.3 和 7.2 节的格式化规则,当然是推荐遵循的。 711 | -------------------------------------------------------------------------------- /docs/guide/google-java-style-guide.md: -------------------------------------------------------------------------------- 1 | # Google Java Style Guide 2 | 3 | ## 1 Introduction 4 | 5 | This document serves as the **complete** definition of Google's coding standards for source code in the Java™ Programming Language. A Java source file is described as being in Google Style if and only if it adheres to the rules herein. 6 | 7 | Like other programming style guides, the issues covered span not only aesthetic issues of formatting, but other types of conventions or coding standards as well. However, this document focuses primarily on the **hard-and-fast** rules that we follow universally, and avoids giving advice that isn't clearly enforceable (whether by human or tool). 8 | 9 | ### 1.1 Terminology notes 10 | 11 | In this document, unless otherwise clarified: 12 | 13 | 1. The term `class` is used inclusively to mean an "ordinary" class, enum class, interface or annotation type (`@interface`). 14 | 2. The term `member` (of a class) is used inclusively to mean a nested class, field, method, or constructor; that is, all top-level contents of a class except initializers and comments. 15 | 3. The term `comment` always refers to implementation comments. We do not use the phrase "documentation comments", instead using the common term "Javadoc." 16 | 17 | Other "terminology notes" will appear occasionally throughout the document. 18 | 19 | ### 1.2 Guide notes 20 | 21 | Example code in this document is **non-normative**. That is, while the examples are in Google Style, they may not illustrate the only stylish way to represent the code. Optional formatting choices made in examples should not be enforced as rules. 22 | 23 | ## 2 Source file basics 24 | 25 | ### 2.1 File name 26 | 27 | The source file name consists of the case-sensitive name of the top-level class it contains (of which there is [exactly one](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s3.4.1-one-top-level-class)), plus the `.java` extension. 28 | 29 | ### 2.2 File encoding: UTF-8 30 | 31 | Source files are encoded in **UTF-8**. 32 | 33 | ### 2.3 Special characters 34 | 35 | #### 2.3.1 Whitespace characters 36 | 37 | Aside from the line terminator sequence, the **ASCII horizontal space character (`0x20`)** is the only whitespace character that appears anywhere in a source file. This implies that: 38 | 39 | 1. All other whitespace characters in string and character literals are escaped. 40 | 2. Tab characters are **not** used for indentation. 41 | 42 | #### 2.3.2 Special escape sequences 43 | 44 | For any character that has a [special escape sequence](http://docs.oracle.com/javase/tutorial/java/data/characters.html) (`\b`, `\t`, `\n`, `\f`, `\r`, `\"`, `\'` and `\\`), that sequence is used rather than the corresponding octal (e.g. `\012`) or Unicode (e.g. `\u000a`) escape. 45 | 46 | #### 2.3.3 Non-ASCII characters 47 | 48 | For the remaining non-ASCII characters, either the actual Unicode character (e.g. `∞`) or the equivalent Unicode escape (e.g. `\u221e`) is used. The choice depends only on which makes the code **easier to read and understand**, although Unicode escapes outside string literals and comments are strongly discouraged. 49 | 50 | > **Tip**: In the Unicode escape case, and occasionally even when actual Unicode characters are used, an explanatory comment can be very helpful. 51 | 52 | Examples: 53 | 54 | | Example | Discussion | 55 | | ------------------------------------------------------ | ------------------------------------------------------------ | 56 | | String unitAbbrev = "μs"; | Best: perfectly clear even without a comment. | 57 | | String unitAbbrev = "\u03bcs"; // "μs" | Allowed, but there's no reason to do this. | 58 | | String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" | Allowed, but awkward and prone to mistakes. | 59 | | String unitAbbrev = "\u03bcs"; | Poor: the reader has no idea what this is. | 60 | | return '\ufeff' + content; // byte order mark | Good: use escapes for non-printable characters, and comment if necessary. | 61 | 62 | > **Tip**: Never make your code less readable simply out of fear that some programs might not handle non-ASCII characters properly. If that should happen, those programs are **broken** and they must be **fixed**. 63 | 64 | ## 3 Source file structure 65 | 66 | A source file consists of, **in order**: 67 | 68 | 1. License or copyright information, if present 69 | 2. Package statement 70 | 3. Import statements 71 | 4. Exactly one top-level class 72 | 73 | **Exactly one blank line** separates each section that is present. 74 | 75 | ### 3.1 License or copyright information, if present 76 | 77 | If license or copyright information belongs in a file, it belongs here. 78 | 79 | ### 3.2 Package statement 80 | 81 | The package statement is **not line-wrapped**. The column limit (Section 4.4, [Column limit: 100](#)) does not apply to package statements. 82 | 83 | ### 3.3 Import statements 84 | 85 | #### 3.3.1 No wildcard imports 86 | 87 | **Wildcard imports**, static or otherwise, **are not used**. 88 | 89 | #### 3.3.2 No line-wrapping 90 | 91 | Import statements are **not line-wrapped**. The column limit (Section 4.4, [Column limit: 100](#)) does not apply to import statements. 92 | 93 | #### 3.3.3 Ordering and spacing 94 | 95 | Imports are ordered as follows: 96 | 97 | 1. All static imports in a single block. 98 | 2. All non-static imports in a single block. 99 | 100 | If there are both static and non-static imports, a single blank line separates the two blocks. There are no other blank lines between import statements. 101 | 102 | Within each block the imported names appear in ASCII sort order. (**Note**: this is not the same as the import statements being in ASCII sort order, since '.' sorts before ';'.) 103 | 104 | #### 3.3.4 No static import for classes 105 | 106 | Static import is not used for static nested classes. They are imported with normal imports. 107 | 108 | ### 3.4 Class declaration 109 | 110 | #### 3.4.1 Exactly one top-level class declaration 111 | 112 | Each top-level class resides in a source file of its own. 113 | 114 | #### 3.4.2 Ordering of class contents 115 | 116 | The order you choose for the members and initializers of your class can have a great effect on learnability. However, there's no single correct recipe for how to do it; different classes may order their contents in different ways. 117 | 118 | What is important is that each class uses **some logical order**, which its maintainer could explain if asked. For example, new methods are not just habitually added to the end of the class, as that would yield "chronological by date added" ordering, which is not a logical ordering. 119 | 120 | ##### 3.4.2.1 Overloads: never split 121 | 122 | When a class has multiple constructors, or multiple methods with the same name, these appear sequentially, with no other code in between (not even private members). 123 | 124 | ## 4 Formatting 125 | 126 | **Terminology Note**: block-like construct refers to the body of a class, method or constructor. Note that, by Section 4.8.3.1 on array initializers, any array initializer may optionally be treated as if it were a block-like construct. 127 | 128 | ### 4.1 Braces 129 | 130 | #### 4.1.1 Braces are used where optional 131 | 132 | Braces are used with if, else, for, do and while statements, even when the body is empty or contains only a single statement. 133 | 134 | #### 4.1.2 Nonempty blocks: K & R style 135 | 136 | Braces follow the Kernighan and Ritchie style (["Egyptian brackets"](http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html)) for nonempty blocks and block-like constructs: 137 | 138 | - No line break before the opening brace. 139 | - Line break after the opening brace. 140 | - Line break before the closing brace. 141 | - Line break after the closing brace, only if that brace terminates a statement or terminates the body of a method, constructor, or named class. For example, there is no line break after the brace if it is followed by `else` or a comma. 142 | 143 | Examples: 144 | 145 | ```java 146 | return () -> { 147 | while (condition()) { 148 | method(); 149 | } 150 | }; 151 | 152 | return new MyClass() { 153 | @Override public void method() { 154 | if (condition()) { 155 | try { 156 | something(); 157 | } catch (ProblemException e) { 158 | recover(); 159 | } 160 | } else if (otherCondition()) { 161 | somethingElse(); 162 | } else { 163 | lastThing(); 164 | } 165 | } 166 | }; 167 | ``` 168 | 169 | A few exceptions for enum classes are given in Section 4.8.1, [Enum classes](https://checkstyle.sourceforge.io/styleguides/google-java-style-20180523/javaguide.html#s4.8.1-enum-classes). 170 | 171 | #### 4.1.3 Empty blocks: may be concise 172 | 173 | An empty block or block-like construct may be in K & R style (as described in Section 4.1.2). Alternatively, it may be closed immediately after it is opened, with no characters or line break in between ({}), unless it is part of a multi-block statement (one that directly contains multiple blocks: if/else or try/catch/finally). 174 | 175 | Examples: 176 | 177 | ```java 178 | // This is acceptable 179 | void doNothing() {} 180 | 181 | // This is equally acceptable 182 | void doNothingElse() { 183 | } 184 | ``` 185 | 186 | ```java 187 | // This is not acceptable: No concise empty blocks in a multi-block statement 188 | try { 189 | doSomething(); 190 | } catch (Exception e) {} 191 | ``` 192 | 193 | ### 4.2 Block indentation: +2 spaces 194 | 195 | Each time a new block or block-like construct is opened, the indent increases by two spaces. When the block ends, the indent returns to the previous indent level. The indent level applies to both code and comments throughout the block. (See the example in Section 4.1.2, [Nonempty blocks: K & R Style](#).) 196 | 197 | ### 4.3 One statement per line 198 | 199 | Each statement is followed by a line break. 200 | 201 | ### 4.4 Column limit: 100 202 | 203 | Java code has a column limit of 100 characters. A "character" means any Unicode code point. Except as noted below, any line that would exceed this limit must be line-wrapped, as explained in Section 4.5, [Line-wrapping](#). 204 | 205 | > Each Unicode code point counts as one character, even if its display width is greater or less. For example, if using [fullwidth characters](https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms), you may choose to wrap the line earlier than where this rule strictly requires. 206 | 207 | Exceptions: 208 | 209 | 1. Lines where obeying the column limit is not possible (for example, a long URL in Javadoc, or a long JSNI method reference). 210 | 2. `package` and `import` statements (see Sections 3.2 [Package statement](#) and 3.3 [Import statements](#)). 211 | 3. Command lines in a comment that may be cut-and-pasted into a shell. 212 | 213 | ### 4.5 Line-wrapping 214 | 215 | **Terminology Note**: When code that might otherwise legally occupy a single line is divided into multiple lines, this activity is called line-wrapping. 216 | 217 | There is no comprehensive, deterministic formula showing exactly how to line-wrap in every situation. Very often there are several valid ways to line-wrap the same piece of code. 218 | 219 | > **Note**: While the typical reason for line-wrapping is to avoid overflowing the column limit, even code that would in fact fit within the column limit may be line-wrapped at the author's discretion. 220 | 221 | > **Tip**: Extracting a method or local variable may solve the problem without the need to line-wrap. 222 | 223 | #### 4.5.1 Where to break 224 | 225 | The prime directive of line-wrapping is: prefer to break at a **higher syntactic level**. Also: 226 | 227 | 1. When a line is broken at a non-assignment operator the break comes before the symbol. (Note that this is not the same practice used in Google style for other languages, such as C++ and JavaScript.) 228 | - This also applies to the following "operator-like" symbols: 229 | - the dot separator (`.`) 230 | - the two colons of a method reference (`::`) 231 | - an ampersand in a type bound (``) 232 | - a pipe in a catch block (`catch (FooException | BarException e)`). 233 | 2. When a line is broken at an assignment operator the break typically comes after the symbol, but either way is acceptable. 234 | - This also applies to the "assignment-operator-like" colon in an enhanced `for` ("`foreach`") statement. 235 | 3. A method or constructor name stays attached to the open parenthesis (`(`) that follows it. 236 | 4. A comma (`,`) stays attached to the token that precedes it. 237 | 5. A line is never broken adjacent to the arrow in a lambda, except that a break may come immediately after the arrow if the body of the lambda consists of a single unbraced expression. Examples: 238 | 239 | ```java 240 | MyLambda lambda = 241 | (String label, Long value, Object obj) -> { 242 | ... 243 | }; 244 | 245 | Predicate predicate = str -> 246 | longExpressionInvolving(str); 247 | ``` 248 | 249 | > **Note**: The primary goal for line wrapping is to have clear code, not necessarily code that fits in the smallest number of lines. 250 | 251 | #### 4.5.2 Indent continuation lines at least +4 spaces 252 | 253 | When line-wrapping, each line after the first (each continuation line) is indented at least +4 from the original line. 254 | 255 | When there are multiple continuation lines, indentation may be varied beyond +4 as desired. In general, two continuation lines use the same indentation level if and only if they begin with syntactically parallel elements. 256 | 257 | Section 4.6.3 on [Horizontal alignment](#) addresses the discouraged practice of using a variable number of spaces to align certain tokens with previous lines. 258 | 259 | ### 4.6 Whitespace 260 | 261 | #### 4.6.1 Vertical Whitespace 262 | 263 | A single blank line always appears: 264 | 265 | 1. Between consecutive members or initializers of a class: fields, constructors, methods, nested classes, static initializers, and instance initializers. 266 | - **Exception**: A blank line between two consecutive fields (having no other code between them) is optional. Such blank lines are used as needed to create logical groupings of fields. 267 | - **Exception**: Blank lines between enum constants are covered in [Section 4.8.1](#). 268 | 1. As required by other sections of this document (such as Section 3, [Source file structure](#), and Section 3.3, [Import statements](#)). 269 | 270 | A single blank line may also appear anywhere it improves readability, for example between statements to organize the code into logical subsections. A blank line before the first member or initializer, or after the last member or initializer of the class, is neither encouraged nor discouraged. 271 | 272 | Multiple consecutive blank lines are permitted, but never required (or encouraged). 273 | 274 | #### 4.6.2 Horizontal whitespace 275 | 276 | Beyond where required by the language or other style rules, and apart from literals, comments and Javadoc, a single ASCII space also appears in the following places only. 277 | 278 | 1. Separating any reserved word, such as `if`, `for` or `catch`, from an open parenthesis (`(`) that follows it on that line 279 | 2. Separating any reserved word, such as `else` or `catch`, from a closing curly brace (`}`) that precedes it on that line 280 | 3. Before any open curly brace (`{`), with two exceptions: 281 | - `@SomeAnnotation({a, b})` (no space is used) 282 | - `String[][] x = {{"foo"}};` (no space is required between {{, by item 8 below) 283 | 4. On both sides of any binary or ternary operator. This also applies to the following "operator-like" symbols: 284 | - the ampersand in a conjunctive type bound: `` 285 | - the pipe for a catch block that handles multiple exceptions: `catch (FooException | BarException e)` 286 | - the colon (`:`) in an enhanced `for` ("`foreach`") statement 287 | - the arrow in a lambda expression: `(String str) -> str.length()` 288 | but not 289 | - the two colons (`::`) of a method reference, which is written like `Object::toString` 290 | - the dot separator (`.`), which is written like `object.toString()` 291 | 1. After `,:;` or the closing parenthesis (`)`) of a cast 292 | 2. On both sides of the double slash (`//`) that begins an end-of-line comment. Here, multiple spaces are allowed, but not required. 293 | 3. Between the type and variable of a declaration: `List list` 294 | 4. Optional just inside both braces of an array initializer 295 | - `new int[] {5, 6}` and `new int[] { 5, 6 }` are both valid 296 | 9. Between a type annotation and `[]` or `...`. 297 | 298 | This rule is never interpreted as requiring or forbidding additional space at the start or end of a line; it addresses only interior space. 299 | 300 | #### 4.6.3 Horizontal alignment: never required 301 | 302 | **Terminology Note**: Horizontal alignment is the practice of adding a variable number of additional spaces in your code with the goal of making certain tokens appear directly below certain other tokens on previous lines. 303 | 304 | This practice is permitted, but is **never required** by Google Style. It is not even required to maintain horizontal alignment in places where it was already used. 305 | 306 | Here is an example without alignment, then using alignment: 307 | 308 | ```java 309 | private int x; // this is fine 310 | private Color color; // this too 311 | 312 | private int x; // permitted, but future edits 313 | private Color color; // may leave it unaligned 314 | ``` 315 | 316 | > **Tip**: Alignment can aid readability, but it creates problems for future maintenance. Consider a future change that needs to touch just one line. This change may leave the formerly-pleasing formatting mangled, and that is **allowed**. More often it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly triggering a cascading series of reformattings. That one-line change now has a "blast radius." This can at worst result in pointless busywork, but at best it still corrupts version history information, slows down reviewers and exacerbates merge conflicts. 317 | 318 | ### 4.7 Grouping parentheses: recommended 319 | 320 | Optional grouping parentheses are omitted only when author and reviewer agree that there is no reasonable chance the code will be misinterpreted without them, nor would they have made the code easier to read. It is not reasonable to assume that every reader has the entire Java operator precedence table memorized. 321 | 322 | ### 4.8 Specific constructs 323 | 324 | #### 4.8.1 Enum classes 325 | 326 | After each comma that follows an enum constant, a line break is optional. Additional blank lines (usually just one) are also allowed. This is one possibility: 327 | 328 | ```java 329 | private enum Answer { 330 | YES { 331 | @Override public String toString() { 332 | return "yes"; 333 | } 334 | }, 335 | 336 | NO, 337 | MAYBE 338 | } 339 | ``` 340 | 341 | An enum class with no methods and no documentation on its constants may optionally be formatted as if it were an array initializer (see Section 4.8.3.1 on [array initializers](#)). 342 | 343 | ```java 344 | private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS } 345 | ``` 346 | 347 | Since enum classes are classes, all other rules for formatting classes apply. 348 | 349 | #### 4.8.2 Variable declarations 350 | 351 | ##### 4.8.2.1 One variable per declaration 352 | 353 | Every variable declaration (field or local) declares only one variable: declarations such as `int a, b;` are not used. 354 | 355 | **Exception**: Multiple variable declarations are acceptable in the header of a `for` loop. 356 | 357 | ##### 4.8.2.2 Declared when needed 358 | 359 | Local variables are not habitually declared at the start of their containing block or block-like construct. Instead, local variables are declared close to the point they are first used (within reason), to minimize their scope. Local variable declarations typically have initializers, or are initialized immediately after declaration. 360 | 361 | #### 4.8.3 Arrays 362 | 363 | ##### 4.8.3.1 Array initializers: can be "block-like" 364 | 365 | Any array initializer may optionally be formatted as if it were a "block-like construct." For example, the following are all valid (**not** an exhaustive list): 366 | 367 | ```java 368 | new int[] { new int[] { 369 | 0, 1, 2, 3 0, 370 | } 1, 371 | 2, 372 | new int[] { 3, 373 | 0, 1, } 374 | 2, 3 375 | } new int[] 376 | {0, 1, 2, 3} 377 | ``` 378 | 379 | ##### 4.8.3.2 No C-style array declarations 380 | 381 | The square brackets form a part of the type, not the variable: `String[] args`, not `String args[]`. 382 | 383 | #### 4.8.4 Switch statements 384 | 385 | **Terminology Note**: Inside the braces of a switch block are one or more statement groups. Each statement group consists of one or more switch labels (either case FOO: or default:), followed by one or more statements (or, for the last statement group, zero or more statements). 386 | 387 | ##### 4.8.4.1 Indentation 388 | 389 | As with any other block, the contents of a switch block are indented +2. 390 | 391 | After a switch label, there is a line break, and the indentation level is increased +2, exactly as if a block were being opened. The following switch label returns to the previous indentation level, as if a block had been closed. 392 | 393 | ##### 4.8.4.2 Fall-through: commented 394 | 395 | Within a switch block, each statement group either terminates abruptly (with a break, continue, return or thrown exception), or is marked with a comment to indicate that execution will or might continue into the next statement group. Any comment that communicates the idea of fall-through is sufficient (typically // fall through). This special comment is not required in the last statement group of the switch block. Example: 396 | 397 | ```java 398 | switch (input) { 399 | case 1: 400 | case 2: 401 | prepareOneOrTwo(); 402 | // fall through 403 | case 3: 404 | handleOneTwoOrThree(); 405 | break; 406 | default: 407 | handleLargeNumber(input); 408 | } 409 | ``` 410 | 411 | Notice that no comment is needed after case 1:, only at the end of the statement group. 412 | 413 | ##### 4.8.4.3 The default case is present 414 | 415 | Each switch statement includes a `default` statement group, even if it contains no code. 416 | 417 | **Exception**: A switch statement for an `enum` type may omit the `default` statement group, if it includes explicit cases covering all possible values of that type. This enables IDEs or other static analysis tools to issue a warning if any cases were missed. 418 | 419 | #### 4.8.5 Annotations 420 | 421 | Annotations applying to a class, method or constructor appear immediately after the documentation block, and each annotation is listed on a line of its own (that is, one annotation per line). These line breaks do not constitute line-wrapping (Section 4.5, [Line-wrapping](#)), so the indentation level is not increased. Example: 422 | 423 | ```java 424 | @Override 425 | @Nullable 426 | public String getNameIfPresent() { ... } 427 | ``` 428 | 429 | **Exception**: A single parameterless annotation may instead appear together with the first line of the signature, for example: 430 | 431 | ```java 432 | @Override public int hashCode() { ... } 433 | ``` 434 | 435 | Annotations applying to a field also appear immediately after the documentation block, but in this case, multiple annotations (possibly parameterized) may be listed on the same line; for example: 436 | 437 | ```java 438 | @Partial @Mock DataLoader loader; 439 | ``` 440 | 441 | There are no specific rules for formatting annotations on parameters, local variables, or types. 442 | 443 | #### 4.8.6 Comments 444 | 445 | This section addresses implementation comments. Javadoc is addressed separately in Section 7, Javadoc. 446 | 447 | Any line break may be preceded by arbitrary whitespace followed by an implementation comment. Such a comment renders the line non-blank. 448 | 449 | ##### 4.8.6.1 Block comment style 450 | 451 | Block comments are indented at the same level as the surrounding code. They may be in `/* ... */` style or `// ...` style. For multi-line `/* ... */` comments, subsequent lines must start with `*` aligned with the `*` on the previous line. 452 | 453 | ```java 454 | /* 455 | * This is // And so /* Or you can 456 | * okay. // is this. * even do this. */ 457 | */ 458 | ``` 459 | 460 | Comments are not enclosed in boxes drawn with asterisks or other characters. 461 | 462 | **Tip**: When writing multi-line comments, use the `/* ... */` style if you want automatic code formatters to re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in `// ...` style comment blocks. 463 | 464 | #### 4.8.7 Modifiers 465 | 466 | Class and member modifiers, when present, appear in the order recommended by the Java Language Specification: 467 | 468 | ```java 469 | public protected private abstract default static final transient volatile synchronized native strictfp 470 | ``` 471 | 472 | #### 4.8.8 Numeric Literals 473 | 474 | `long`-valued integer literals use an uppercase `L` suffix, never lowercase (to avoid confusion with the digit `1`). For example, `3000000000L` rather than `3000000000l`. 475 | 476 | ## 5 Naming 477 | 478 | ### 5.1 Rules common to all identifiers 479 | 480 | Identifiers use only ASCII letters and digits, and, in a small number of cases noted below, underscores. Thus each valid identifier name is matched by the regular expression \w+ . 481 | 482 | In Google Style, special prefixes or suffixes are not used. For example, these names are not Google Style: `name_`, `mName`, `s_name` and `kName`. 483 | 484 | ### 5.2 Rules by identifier type 485 | 486 | #### 5.2.1 Package names 487 | 488 | Package names are all lowercase, with consecutive words simply concatenated together (no underscores). For example, `com.example.deepspace`, not `com.example.deepSpace` or `com.example.deep_space`. 489 | 490 | #### 5.2.2 Class names 491 | 492 | Class names are written in [UpperCamelCase](#). 493 | 494 | Class names are typically nouns or noun phrases. For example, `Character` or `ImmutableList`. Interface names may also be nouns or noun phrases (for example, `List`), but may sometimes be adjectives or adjective phrases instead (for example, `Readable`). 495 | 496 | There are no specific rules or even well-established conventions for naming annotation types. 497 | 498 | Test classes are named starting with the name of the class they are testing, and ending with Test. For example, `HashTest` or `HashIntegrationTest`. 499 | 500 | #### 5.2.3 Method names 501 | 502 | Method names are written in [lowerCamelCase](#). 503 | 504 | Method names are typically verbs or verb phrases. For example, `sendMessage` or `stop`. 505 | 506 | Underscores may appear in JUnit test method names to separate logical components of the name, with each component written in [lowerCamelCase](). One typical pattern is `_`, for example `pop_emptyStack`. There is no One Correct Way to name test methods. 507 | 508 | #### 5.2.4 Constant names 509 | 510 | Constant names use `CONSTANT_CASE`: all uppercase letters, with each word separated from the next by a single underscore. But what is a constant, exactly? 511 | 512 | Constants are static final fields whose contents are deeply immutable and whose methods have no detectable side effects. This includes primitives, Strings, immutable types, and immutable collections of immutable types. If any of the instance's observable state can change, it is not a constant. Merely intending to never mutate the object is not enough. Examples: 513 | 514 | ```java 515 | // Constants 516 | static final int NUMBER = 5; 517 | static final ImmutableList NAMES = ImmutableList.of("Ed", "Ann"); 518 | static final ImmutableMap AGES = ImmutableMap.of("Ed", 35, "Ann", 32); 519 | static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable 520 | static final SomeMutableType[] EMPTY_ARRAY = {}; 521 | enum SomeEnum { ENUM_CONSTANT } 522 | 523 | // Not constants 524 | static String nonFinal = "non-final"; 525 | final String nonStatic = "non-static"; 526 | static final Set mutableCollection = new HashSet(); 527 | static final ImmutableSet mutableElements = ImmutableSet.of(mutable); 528 | static final ImmutableMap mutableValues = 529 | ImmutableMap.of("Ed", mutableInstance, "Ann", mutableInstance2); 530 | static final Logger logger = Logger.getLogger(MyClass.getName()); 531 | static final String[] nonEmptyArray = {"these", "can", "change"}; 532 | ``` 533 | 534 | These names are typically nouns or noun phrases. 535 | 536 | #### 5.2.5 Non-constant field names 537 | 538 | Non-constant field names (static or otherwise) are written in `lowerCamelCase`. 539 | 540 | These names are typically nouns or noun phrases. For example, `computedValues` or `index`. 541 | 542 | #### 5.2.6 Parameter names 543 | 544 | Parameter names are written in `lowerCamelCase`. 545 | 546 | One-character parameter names in public methods should be avoided. 547 | 548 | #### 5.2.7 Local variable names 549 | 550 | Local variable names are written in `lowerCamelCase`. 551 | 552 | Even when `final` and immutable, local variables are not considered to be constants, and should not be styled as constants. 553 | 554 | #### 5.2.8 Type variable names 555 | 556 | Each type variable is named in one of two styles: 557 | 558 | A single capital letter, optionally followed by a single numeral (such as `E`, `T`, `X`, `T2`) 559 | A name in the form used for classes (see Section 5.2.2, [Class names](#)), followed by the capital letter `T` (examples: `RequestT`, `FooBarT`). 560 | 561 | ### 5.3 Camel case: defined 562 | 563 | Sometimes there is more than one reasonable way to convert an English phrase into camel case, such as when acronyms or unusual constructs like "`IPv6`" or "`iOS`" are present. To improve predictability, Google Style specifies the following (nearly) deterministic scheme. 564 | 565 | Beginning with the prose form of the name: 566 | 567 | 1. Convert the phrase to plain ASCII and remove any apostrophes. For example, "Müller's algorithm" might become "Muellers algorithm". 568 | 2. Divide this result into words, splitting on spaces and any remaining punctuation (typically hyphens). 569 | - **Recommended**: if any word already has a conventional camel-case appearance in common usage, split this into its constituent parts (e.g., "AdWords" becomes "ad words"). Note that a word such as "iOS" is not really in camel case per se; it defies any convention, so this recommendation does not apply. 570 | 3. Now lowercase everything (including acronyms), then uppercase only the first character of: 571 | - each word, to yield upper camel case, or 572 | - each word except the first, to yield lower camel case 573 | 4. Finally, join all the words into a single identifier. 574 | 575 | Note that the casing of the original words is almost entirely disregarded. Examples: 576 | 577 | | Prose form | Correct | Incorrect | 578 | | ------------ | ------------ | ------------ | 579 | | "XML HTTP request" | XmlHttpRequest | XMLHTTPRequest | 580 | | "new customer ID" | newCustomerId | newCustomerID | 581 | | "inner stopwatch" | innerStopwatch | innerStopWatch | 582 | | "supports IPv6 on iOS?" | supportsIpv6OnIos | supportsIPv6OnIOS | 583 | | "YouTube importer" | YouTubeImporter YoutubeImporter* | 无 | 584 | 585 | Note: Some words are ambiguously hyphenated in the English language: for example "nonempty" and "non-empty" are both correct, so the method names `checkNonempty` and `checkNonEmpty` are likewise both correct. 586 | 587 | ## 6 Programming Practices 588 | 589 | ### 6.1 @Override: always used 590 | 591 | A method is marked with the `@Override` annotation whenever it is legal. This includes a class method overriding a superclass method, a class method implementing an interface method, and an interface method respecifying a superinterface method. 592 | 593 | **Exception**: `@Override` may be omitted when the parent method is @Deprecated. 594 | 595 | ### 6.2 Caught exceptions: not ignored 596 | 597 | Except as noted below, it is very rarely correct to do nothing in response to a caught exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an `AssertionError`.) 598 | 599 | When it truly is appropriate to take no action whatsoever in a catch block, the reason this is justified is explained in a comment. 600 | 601 | ```java 602 | try { 603 | int i = Integer.parseInt(response); 604 | return handleNumericResponse(i); 605 | } catch (NumberFormatException ok) { 606 | // it's not numeric; that's fine, just continue 607 | } 608 | return handleTextResponse(response); 609 | ``` 610 | 611 | **Exception**: In tests, a caught exception may be ignored without comment if its name is or begins with `expected`. The following is a very common idiom for ensuring that the code under test does throw an exception of the expected type, so a comment is unnecessary here. 612 | 613 | ```java 614 | try { 615 | emptyStack.pop(); 616 | fail(); 617 | } catch (NoSuchElementException expected) { 618 | } 619 | ``` 620 | 621 | ### 6.3 Static members: qualified using class 622 | 623 | When a reference to a static class member must be qualified, it is qualified with that class's name, not with a reference or expression of that class's type. 624 | 625 | ```java 626 | Foo aFoo = ...; 627 | Foo.aStaticMethod(); // good 628 | aFoo.aStaticMethod(); // bad 629 | somethingThatYieldsAFoo().aStaticMethod(); // very bad 630 | ``` 631 | 632 | ### 6.4 Finalizers: not used 633 | 634 | It is **extremely rare** to override `Object.finalize`. 635 | 636 | > **Tip**: Don't do it. If you absolutely must, first read and understand [Effective Java Item 7](http://books.google.com/books?isbn=8131726592), "Avoid Finalizers," very carefully, and then don't do it. 637 | 638 | ## 7 Javadoc 639 | 640 | ### 7.1 Formatting 641 | 642 | #### 7.1.1 General form 643 | 644 | The basic formatting of Javadoc blocks is as seen in this example: 645 | 646 | ```java 647 | /** 648 | * 这里写了多行 Javadoc 文本, 649 | * 正常包裹... 650 | */ 651 | public int method(String p1) { ... } 652 | ``` 653 | 654 | ... or in this single-line example: 655 | 656 | ```java 657 | /** An especially short bit of Javadoc. */ 658 | ``` 659 | 660 | The basic form is always acceptable. The single-line form may be substituted when the entirety of the Javadoc block (including comment markers) can fit on a single line. Note that this only applies when there are no block tags such as `@return`. 661 | 662 | #### 7.1.2 Paragraphs 663 | 664 | One blank line—that is, a line containing only the aligned leading asterisk (`*`)—appears between paragraphs, and before the group of block tags if present. Each paragraph but the first has `

` immediately before the first word, with no space after. 665 | 666 | #### 7.1.3 Block tags 667 | 668 | Any of the standard "block tags" that are used appear in the order `@param`, `@return`, `@throws`, `@deprecated`, and these four types never appear with an empty description. When a block tag doesn't fit on a single line, continuation lines are indented `four` (or more) spaces from the position of the `@`. 669 | 670 | ### 7.2 The summary fragment 671 | 672 | Each Javadoc block begins with a brief **summary fragment**. This fragment is very important: it is the only part of the text that appears in certain contexts such as class and method indexes. 673 | 674 | This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does not begin with `A {@code Foo} is a...`, or `This method returns...`, nor does it form a complete imperative sentence like `Save the record.`. However, the fragment is capitalized and punctuated as if it were a complete sentence. 675 | 676 | Tip: A common mistake is to write simple Javadoc in the form `/** @return the customer ID */`. This is incorrect, and should be changed to `/** Returns the customer ID. */`. 677 | 678 | ### 7.3 Where Javadoc is used 679 | 680 | At the minimum, Javadoc is present for every `public` class, and every `public` or `protected` member of such a class, with a few exceptions noted below. 681 | 682 | Additional Javadoc content may also be present, as explained in Section 7.3.4, [Non-required Javadoc](#). 683 | 684 | #### 7.3.1 Exception: self-explanatory methods 685 | 686 | Javadoc is optional for "simple, obvious" methods like getFoo, in cases where there really and truly is nothing else worthwhile to say but "`Returns the foo`". 687 | 688 | Important: it is not appropriate to cite this exception to justify omitting relevant information that a typical reader might need to know. For example, for a method named `getCanonicalName`, don't omit its documentation (with the rationale that it would say only `/** Returns the canonical name. */`) if a typical reader may have no idea what the term "canonical name" means! 689 | 690 | #### 7.3.2 Exception: overrides 691 | 692 | Javadoc is not always present on a method that overrides a supertype method. 693 | 694 | #### 7.3.4 Non-required Javadoc 695 | 696 | Other classes and members have Javadoc as needed or desired. 697 | 698 | Whenever an implementation comment would be used to define the overall purpose or behavior of a class or member, that comment is written as Javadoc instead (using `/**`). 699 | 700 | Non-required Javadoc is not strictly required to follow the formatting rules of Sections 7.1.2, 7.1.3, and 7.2, though it is of course recommended. 701 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blinkfox Java 编程风格指南 6 | 7 | 9 | 11 | 13 | 14 | 15 | 16 | 17 |

加载中...
18 | 19 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/styles/blinkfox-checks.md: -------------------------------------------------------------------------------- 1 | # 📝 Blinkfox CheckStyle 文件 2 | 3 | 本 `blinkfox-checks.xml` 文件是基于 Google CheckStyle 文件而修改的符合 [Blinkfox 编程风格指南](guide/blinkfox-java-style-guide.md)的 checkstyle 文件。点击下载《[blinkfox-checks.xml](https://github.com/blinkfox/java-style/blob/master/docs/checks/blinkfox-checks.xml)》。 4 | 5 | - 查看[如何使用](README?id=maven-blinkfox-checks)。 6 | 7 | [blinkfox-checks.xml](../checks/blinkfox-checks.xml ':include :type=code') 8 | -------------------------------------------------------------------------------- /docs/styles/blinkfox-idea-java-style.md: -------------------------------------------------------------------------------- 1 | # Blinkfox IDEA Java Code Style 文件 2 | 3 | 本 `blinkfox-idea-java-style.xml` 是一个用于导入到 Intellij IDEA 中的代码格式化配置文件。点击下载[《blinkfox-idea-java-style.xml》](https://github.com/blinkfox/java-style/blob/master/docs/checks/blinkfox-idea-java-style.xml)。 4 | 5 | - 查看[如何使用](README?id=idea-java-style)。 6 | 7 | [blinkfox-idea-java-style.xml](../checks/blinkfox-idea-java-style.xml ':include :type=code') 8 | -------------------------------------------------------------------------------- /docs/styles/google-checks.md: -------------------------------------------------------------------------------- 1 | # Google CheckStyle 2 | 3 | 本 `google-checks.xml` 是 Google 原生提供的 Checkstyle 文件。点击下载[《google-checks.xml》](https://github.com/blinkfox/java-style/blob/master/docs/checks/google-checks.xml)。 4 | 5 | [google-checks.xml](../checks/google-checks.xml ':include :type=code') 6 | --------------------------------------------------------------------------------