blob: 7b8b2ef7e47ae83902bd0f76c749bb9be8396f87 [file] [log] [blame] [view]
nyquist9d61f982017-02-10 00:29:081# Chromium Java style guide
2
3_For other languages, please see the [Chromium style
4guides](https://chromium.googlesource.com/chromium/src/+/master/styleguide/styleguide.md)._
5
6Chromium follows the [Android Open Source style
7guide](http://source.android.com/source/code-style.html) unless an exception
8is listed below.
9
nyquistaae4c7c2017-02-15 20:41:4210You can propose changes to this style guide by sending an email to
11`[email protected]`. Ideally, the list will arrive at some consensus and you can
12request review for a change to this file. If there's no consensus,
13[`//styleguide/java/OWNERS`](https://chromium.googlesource.com/chromium/src/+/master/styleguide/java/OWNERS)
14get to decide.
15
agrieve0e6bdf22018-08-03 14:25:2416[TOC]
17
18## Java 8 Language Features
19[Desugar](https://github.com/bazelbuild/bazel/blob/master/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java)
20is used to rewrite some Java 7 & 8 language constructs in a way that is
21compatible with Java 6 (and thus all Android versions). Use of
22[these features](https://developer.android.com/studio/write/java8-support)
23is encouraged, but there are some gotchas:
24
25### Default Interface Methods
26 * Desugar makes default interface methods work by copy & pasting the default
27 implementations into all implementing classes.
28 * This technique is fine for infrequently-used interfaces, but should be
29 avoided (e.g. via a base class) if it noticeably increases method count.
30
31### Lambdas and Method References
32 * These are syntactic sugar for creating anonymous inner classes.
33 * Use them only where the cost of an extra class & method definition is
34 justified.
35
36### try-with-resources
37 * Some library classes do not implement Closeable on older platform APIs.
38 Runtime exceptions are thrown if you use them with a try-with-resources.
39 Do not use the following classes in a try-with-resources:
40 * java.util.zip.ZipFile (implemented in API 19)
41 * java.net.Socket (implemented in API 19)
42
agrieve398286b2018-08-15 01:44:4543## Other Language Features & APIs
44
45### Exceptions
46* As with the Android style guide, we discourage overly broad catches via
47`Exception` / `Throwable` / `RuntimeException`.
48 * If you need to have a broad catch expression, use a comment to explain why.
49* Catching multiple exceptions in one line is fine.
50
51It is OK to do:
52```java
53try {
54 somethingThatThrowsIOException(filePath);
55 somethingThatThrowsParseException(filePath);
56} catch (IOException | ParseException e) {
57 Log.w(TAG, "Failed to read: %s", filePath, e);
58}
59```
60
61### Logging
62* Use `org.chromium.base.Log` instead of `android.util.Log`.
63 * It provides `%s` support, and ensures log stripping works correctly.
64* Minimize the use of `Log.w()` and `Log.e()`.
65 * Debug and Info log levels are stripped by ProGuard in release builds, and
66 so have no performance impact for shipping builds. However, Warning and
67 Error log levels are not stripped.
68* Function calls in log parameters are *not* stripped by ProGuard.
69
70```java
71Log.d(TAG, "There are %d cats", countCats()); // countCats() not stripped.
72```
73
74### Asserts
75The Chromium build system strips asserts in release builds (via ProGuard) and
76enables them in debug builds (or when `dcheck_always_on=true`) (via a [build
77step](https://codereview.chromium.org/2517203002)). You should use asserts in
78the [same
79scenarios](https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md#CHECK_DCHECK_and-NOTREACHED)
80where C++ DCHECK()s make sense. For multi-statement asserts, use
81`org.chromium.base.BuildConfig.DCHECK_IS_ON` to guard your code.
82
83Example assert:
84
85```java
86assert someCallWithoutSideEffects() : "assert description";
87```
88
89Example use of `DCHECK_IS_ON`:
90
91```java
92if (org.chromium.base.BuildConfig.DCHECK_IS_ON) {
93 // Any code here will be stripped in Release by ProGuard.
94 ...
95}
96```
97
98### Other Android Support Library Annotations
99* Use them! They are [documented here](https://developer.android.com/studio/write/annotations).
100 * They generally improve readability.
101 * Some make lint more useful.
102* `javax.annotation.Nullable` vs `android.support.annotation.Nullable`
103 * Always prefer `android.support.annotation.Nullable`.
104 * It uses `@Retention(SOURCE)` rather than `@Retention(RUNTIME)`.
105
nyquistaae4c7c2017-02-15 20:41:42106## Tools
107
108### Automatically formatting edited files
agrieve0e6bdf22018-08-03 14:25:24109A checkout should give you clang-format to automatically format Java code.
110It is suggested that Clang's formatting of code should be accepted in code
111reviews.
112
nyquistaae4c7c2017-02-15 20:41:42113You can run `git cl format` to apply the automatic formatting.
114
agrieve398286b2018-08-15 01:44:45115### IDE Setup
nyquistaae4c7c2017-02-15 20:41:42116For automatically using the correct style, follow the guide to set up your
117favorite IDE:
118
119* [Android Studio](https://chromium.googlesource.com/chromium/src/+/master/docs/android_studio.md)
120* [Eclipse](https://chromium.googlesource.com/chromium/src/+/master/docs/eclipse.md)
121
122### Checkstyle
nyquistaae4c7c2017-02-15 20:41:42123Checkstyle is automatically run by the build bots, and to ensure you do not have
124any surprises, you can also set up checkstyle locally using [this
125guide](https://sites.google.com/a/chromium.org/dev/developers/checkstyle).
126
127### Lint
nyquistaae4c7c2017-02-15 20:41:42128Lint is run as part of the build. For more information, see
129[here](https://chromium.googlesource.com/chromium/src/+/master/build/android/docs/lint.md).
130
agrieve398286b2018-08-15 01:44:45131## Style / Formatting
nyquistaae4c7c2017-02-15 20:41:42132
agrieve398286b2018-08-15 01:44:45133### File Headers
134* Use the same format as in the [C++ style guide](https://chromium.googlesource.com/chromium/src/+/master/styleguide/c++/c++.md#File-headers).
nyquistaae4c7c2017-02-15 20:41:42135
agrieve398286b2018-08-15 01:44:45136### TODOs
137* TODO should follow chromium convention. Examples:
138 * `TODO(username): Some sentence here.`
139 * `TODO(crbug.com/123456): Even better to use a bug for context.`
nyquistaae4c7c2017-02-15 20:41:42140
agrieve398286b2018-08-15 01:44:45141### Code formatting
nyquist9d61f982017-02-10 00:29:08142* Fields should not be explicitly initialized to default values (see
143 [here](https://groups.google.com/a/chromium.org/d/topic/chromium-dev/ylbLOvLs0bs/discussion)).
nyquistaae4c7c2017-02-15 20:41:42144
145### Curly braces
nyquistaae4c7c2017-02-15 20:41:42146Conditional braces should be used, but are optional if the conditional and the
147statement can be on a single line.
148
149Do:
150
151```java
152if (someConditional) return false;
153for (int i = 0; i < 10; ++i) callThing(i);
154```
155
156or
157
158```java
159if (someConditional) {
160 return false;
161}
162```
163
164Do NOT do:
165
166```java
167if (someConditional)
168 return false;
169```
170
nyquist2d192c4c2017-03-06 21:36:51171### Import Order
nyquist2d192c4c2017-03-06 21:36:51172* Static imports go before other imports.
173* Each import group must be separated by an empty line.
174
175This is the order of the import groups:
176
1771. android
1781. com (except com.google.android.apps.chrome)
1791. dalvik
1801. junit
1811. org
1821. com.google.android.apps.chrome
1831. org.chromium
1841. java
1851. javax
186
187This is enforced by the
188[Chromium Checkstyle configuration](../../tools/android/checkstyle/chromium-style-5.0.xml)
189under the ImportOrder module.
190
nyquist9d61f982017-02-10 00:29:08191## Location
nyquist9d61f982017-02-10 00:29:08192"Top level directories" are defined as directories with a GN file, such as
193[//base](https://chromium.googlesource.com/chromium/src/+/master/base/)
194and
195[//content](https://chromium.googlesource.com/chromium/src/+/master/content/),
196Chromium Java should live in a directory named
197`<top level directory>/android/java`, with a package name
198`org.chromium.<top level directory>`. Each top level directory's Java should
199build into a distinct JAR that honors the abstraction specified in a native
200[checkdeps](https://chromium.googlesource.com/chromium/buildtools/+/master/checkdeps/checkdeps.py)
201(e.g. `org.chromium.base` does not import `org.chromium.content`). The full
202path of any java file should contain the complete package name.
203
204For example, top level directory `//base` might contain a file named
205`base/android/java/org/chromium/base/Class.java`. This would get compiled into a
206`chromium_base.jar` (final JAR name TBD).
207
208`org.chromium.chrome.browser.foo.Class` would live in
209`chrome/android/java/org/chromium/chrome/browser/foo/Class.java`.
210
211New `<top level directory>/android` directories should have an `OWNERS` file
212much like
213[//base/android/OWNERS](https://chromium.googlesource.com/chromium/src/+/master/base/android/OWNERS).
214
nyquistaae4c7c2017-02-15 20:41:42215## Miscellany
nyquistaae4c7c2017-02-15 20:41:42216* Use UTF-8 file encodings and LF line endings.