blob: b10b9eb362721cfe6616f12b7fa5612e55cec7de [file] [log] [blame] [view]
Andrew Grieve8d9e40f2023-03-15 21:04:421# Chromium Java Style Guide
nyquist9d61f982017-02-10 00:29:082
3_For other languages, please see the [Chromium style
John Palmerbe051302021-05-19 11:48:354guides](https://chromium.googlesource.com/chromium/src/+/main/styleguide/styleguide.md)._
nyquist9d61f982017-02-10 00:29:085
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`java@chromium.org`. Ideally, the list will arrive at some consensus and you can
12request review for a change to this file. If there's no consensus,
John Palmerbe051302021-05-19 11:48:3513[`//styleguide/java/OWNERS`](https://chromium.googlesource.com/chromium/src/+/main/styleguide/java/OWNERS)
nyquistaae4c7c2017-02-15 20:41:4214get to decide.
15
agrieve0e6bdf22018-08-03 14:25:2416[TOC]
17
Andrew Grieve99e388f2023-11-02 20:46:5118## Java Language Features
Nate Fischer03308e92022-11-07 18:14:5919
Andrew Grieve99e388f2023-11-02 20:46:5120### Type Deduction using "var" {#var}
Nate Fischer03308e92022-11-07 18:14:5921
22A variable declaration can use the `var` keyword in place of the type (similar
23to the `auto` keyword in C++). In line with the [guidance for
24C++](https://google.github.io/styleguide/cppguide.html#Type_deduction), the
25`var` keyword may be used when it aids readability and the type of the value is
26already clear (ex. `var bundle = new Bundle()` is OK, but `var something =
27returnValueIsNotObvious()` may be unclear to readers who are new to this part of
28the code).
29
30The `var` keyword may also be used in try-with-resources when the resource is
31not directly accessed (or when it falls under the previous guidance), such as:
32
33```java
34try (var ignored = StrictModeContext.allowDiskWrites()) {
35 // 'var' is permitted so long as the 'ignored' variable is not used directly
36 // in the code.
37}
38```
39
agrieve398286b2018-08-15 01:44:4540### Exceptions
Andrew Grieve99e388f2023-11-02 20:46:5141
Andrew Grieve1210d142024-06-06 16:31:4742A quick primer:
43
44* `Throwable`: Base class for all exceptions
45 * `Error`: Base class for exceptions which are meant to crash the app.
46 * `Exception`: Base class for exceptions that make sense the `catch`.
47 * `RuntimeException`: Base class for exceptions that do not need to be
48 declared as `throws` ("unchecked exceptions").
49
50#### Broad Catch Handlers {#broad-catches}
51
52Use catch statements that do not catch exceptions they are not meant to.
53 * There is rarely a valid reason to `catch (Throwable t)`, since that
54 includes the (generally unrecoverable) `Error` types.
55
56Use `catch (Exception e)` when working with OS APIs that might throw
57(assuming the program can recover from them).
Andrew Grieve318b35322023-01-13 16:03:2358 * There have been many cases of crashes caused by `IllegalStateException` /
59 `IllegalArgumentException` / `SecurityException` being thrown where only
Andrew Grieve1210d142024-06-06 16:31:4760 `RemoteException` was being caught. Unless catch handlers will differ
61 based on exception type, just catch `Exception`.
62
63Do not use `catch (RuntimeException e)`.
64 * It is useful to extend `RuntimeException` to make unchecked exception
65 types, but the type does not make much sense in `catch` clauses, as
66 there are not times when you'd want to catch all unchecked exceptions,
67 but not also want to catch all checked exceptions.
68
69#### Exception Messages {#exception-messages}
agrieve398286b2018-08-15 01:44:4570
Andrew Grieve318b35322023-01-13 16:03:2371Avoid adding messages to exceptions that do not aid in debugging. For example:
agrieve398286b2018-08-15 01:44:4572
agrieve50430de2018-08-15 17:49:1673```java
74try {
Nate Fischerfc38dc812024-04-24 17:07:2675 somethingThatThrowsIOException();
agrieve50430de2018-08-15 17:49:1676} catch (IOException e) {
Nate Fischerfc38dc812024-04-24 17:07:2677 // Bad - message does not tell you more than the stack trace does:
78 throw new RuntimeException("Failed to parse a file.", e);
79 // Good - conveys that this block failed along with the "caused by" exception.
80 throw new RuntimeException(e);
81 // Good - adds useful information.
82 throw new RuntimeException(String.format("Failed to parse %s", fileName), e);
agrieve50430de2018-08-15 17:49:1683}
84```
85
Andrew Grieve1210d142024-06-06 16:31:4786#### Wrapping with RuntimeException {#throw-unchecked}
87
88It is common to wrap a checked exception with a RuntimeException for cases
89where a checked exception is not recoverable, or not possible. In order to
90reduce the number of stack trace "caused by" clauses, and to save on binary
91size, use [`JavaUtils.throwUnchecked()`] instead.
92
93```java
94try {
95 somethingThatThrowsIOException();
96} catch (IOException e) {
97 // Bad - RuntimeException adds no context and creates longer stack traces.
98 throw new RuntimeException(e);
99 // Good - Original exception is preserved.
100 throw JavaUtils.throwUnchecked(e);
101}
102```
103
104*** note
105Do not use `throwUnchecked()` when the exception may want to be caught.
106***
107
108
109[`JavaUtils.throwUnchecked()`]: https://source.chromium.org/search?q=symbol:JavaUtils.throwUnchecked
110
agrieve398286b2018-08-15 01:44:45111### Asserts
Andrew Grieve8d9e40f2023-03-15 21:04:42112
Andrew Grieve087342762023-07-25 01:14:25113The build system:
114 * strips asserts in release builds (via R8),
115 * enables them in debug builds,
116 * and enables them in report-only mode for Canary builds.
agrieve398286b2018-08-15 01:44:45117
118```java
Andrew Grieve087342762023-07-25 01:14:25119// Code for assert expressions & messages is removed when asserts are disabled.
120assert someCallWithoutSideEffects(param) : "Call failed with: " + param;
agrieve398286b2018-08-15 01:44:45121```
122
Andrew Grieve087342762023-07-25 01:14:25123Use your judgement for when to use asserts vs exceptions. Generally speaking,
124use asserts to check program invariants (e.g. parameter constraints) and
125exceptions for unrecoverable error conditions (e.g. OS errors). You should tend
126to use exceptions more in privacy / security-sensitive code.
127
128Do not add checks when the code will crash anyways. E.g.:
129
130```java
131// Don't do this.
132assert(foo != null);
133foo.method(); // This will throw anyways.
134```
135
136For multi-statement asserts, use [`BuildConfig.ENABLE_ASSERTS`] to guard your
137code (similar to `#if DCHECK_IS_ON()` in C++). E.g.:
agrieve398286b2018-08-15 01:44:45138
139```java
Nate Fischer4570ebc32021-06-04 00:44:45140import org.chromium.build.BuildConfig;
141
142...
143
144if (BuildConfig.ENABLE_ASSERTS) {
Nate Fischerfc38dc812024-04-24 17:07:26145 // Any code here will be stripped in release builds by R8.
146 ...
agrieve398286b2018-08-15 01:44:45147}
148```
149
Andrew Grieve087342762023-07-25 01:14:25150[`BuildConfig.ENABLE_ASSERTS`]: https://source.chromium.org/search?q=symbol:BuildConfig%5C.ENABLE_ASSERTS
151
Andrew Grieve99e388f2023-11-02 20:46:51152#### DCHECKS vs Java Asserts {#asserts}
Andrew Grieve087342762023-07-25 01:14:25153
154`DCHECK` and `assert` are similar, but our guidance for them differs:
155 * CHECKs are preferred in C++, whereas asserts are preferred in Java.
156
157This is because as a memory-safe language, logic bugs in Java are much less
158likely to be exploitable.
159
Andrew Grieve99e388f2023-11-02 20:46:51160### toString() {#toString}
Andrew Grieve8d9e40f2023-03-15 21:04:42161
Andrew Grieve99e388f2023-11-02 20:46:51162Use explicit serialization methods (e.g. `toDebugString()` or `getDescription()`)
163instead of `toString()` when dynamic dispatch is not required.
Andrew Grieve8d9e40f2023-03-15 21:04:42164
Andrew Grieve99e388f2023-11-02 20:46:511651. R8 cannot detect when `toString()` is unused, so overrides will not be stripped
166 when unused.
1672. R8 cannot optimize / inline these calls as well as non-overriding methods.
Andrew Grieve8d9e40f2023-03-15 21:04:42168
Andrew Grieve99e388f2023-11-02 20:46:51169### Records & AutoValue {#records}
170
171```java
172// Banned.
173record Rectangle(float length, float width) {}
174```
175
176**Rationale:**
177 * To avoid dead code:
178 * Records and `@AutoValue` generate `equals()`, `hashCode()`, and `toString()`,
179 which `R8` is unable to remove when unused.
180 * When these methods are required, implement them explicitly so that the
181 intention is clear.
182 * Also - supporting `record` requires build system work ([crbug/1493366]).
183
184Example with `equals()` and `hashCode()`:
185
186```java
187public class ValueClass {
188 private final SomeClass mObjMember;
189 private final int mIntMember;
190
191 @Override
192 public boolean equals(Object o) {
193 return o instanceof ValueClass vc
194 && Objects.equals(mObjMember, vc.mObjMember)
195 && mIntMember == vc.mIntMember;
196 }
197
198 @Override
199 public int hashCode() {
200 return Objects.hash(mObjMember, mIntMember);
201 }
202}
203```
204
205[crbug/1493366]: https://crbug.com/1493366
206
207### Enums
208
209Banned. Use [`@IntDef`](#intdefs) instead.
210
211**Rationale:**
212
213Java enums generate a lot of bytecode. Use constants where possible. When a
214custom type hierarchy is required, use explicit classes with inheritance.
Andrew Grieve8d9e40f2023-03-15 21:04:42215
agrieve16c6fe82018-11-27 17:47:49216### Finalizers
Andrew Grieve8d9e40f2023-03-15 21:04:42217
Andrew Grieveec8284602023-10-16 15:53:25218In line with [Google's Java style guide] and [Android's Java style guide],
agrieve16c6fe82018-11-27 17:47:49219never override `Object.finalize()`.
220
221Custom finalizers:
222* are called on a background thread, and at an unpredicatble point in time,
223* swallow all exceptions (asserts won't work),
224* causes additional garbage collector jank.
225
226Classes that need destructor logic should provide an explicit `destroy()`
John Palmerbe051302021-05-19 11:48:35227method. Use [LifetimeAssert](https://chromium.googlesource.com/chromium/src/+/main/base/android/java/src/org/chromium/base/LifetimeAssert.java)
Bo Liu9bb53ca2020-09-22 00:48:10228to ensure in debug builds and tests that `destroy()` is called.
agrieve16c6fe82018-11-27 17:47:49229
Andrew Grieveec8284602023-10-16 15:53:25230[Google's Java style guide]: https://google.github.io/styleguide/javaguide.html#s6.4-finalizers
231[Android's Java style guide]: https://source.android.com/docs/setup/contribute/code-style#dont-use-finalizers
232
Andrew Grieve19c214d2025-01-14 20:50:06233## Nullability Annotations
234
235A migration to add `@NullMarked` to all Java files is currently underway
Andrew Grieve506d5622025-01-29 21:15:55236([crbug.com/389129271]). See [nullaway.md] for how to use `@Nullable` and
237related annotations.
Andrew Grieve19c214d2025-01-14 20:50:06238
239[crbug.com/389129271]: https://crbug.com/389129271
240[nullaway.md]: nullaway.md
241
Andrew Grieve99e388f2023-11-02 20:46:51242## Java Library APIs
Andrew Grieve8d9e40f2023-03-15 21:04:42243
Andrew Grieve99e388f2023-11-02 20:46:51244Android provides the ability to bundle copies of `java.*` APIs alongside
245application code, known as [Java Library Desugaring]. However, since this
246bundling comes with a performance cost, Chrome does not use it. Treat `java.*`
247APIs the same as you would `android.*` ones and guard them with
248`Build.VERSION.SDK_INT` checks [when necessary]. The one exception is if the
249method is [directly backported by D8] (these are okay to use, since they are
250lightweight). Android Lint will fail if you try to use an API without a
251corresponding `Build.VERSION.SDK_INT` guard or `@RequiresApi` annotation.
252
253[Java Library Desugaring]: https://developer.android.com/studio/write/java8-support-table
254[when necessary]: https://developer.android.com/reference/packages
255[directly backported by D8]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/r8/backported_methods.txt
256
257### Logging
258
259* Use `org.chromium.base.Log` instead of `android.util.Log`.
260 * It provides `%s` support, and ensures log stripping works correctly.
261* Minimize the use of `Log.w()` and `Log.e()`.
262 * Debug and Info log levels are stripped by ProGuard in release builds, and
263 so have no performance impact for shipping builds. However, Warning and
264 Error log levels are not stripped.
265* Function calls in log parameters are *not* stripped by ProGuard.
266
267```java
268Log.d(TAG, "There are %d cats", countCats()); // countCats() not stripped.
269```
270
271### Streams
272
Andrew Grieve31928c92024-11-27 21:00:13273Using [Java streams] outside of tests is strongly discouraged. If you can write
274your code as an explicit loop, then do so. The primary reason for this guidance
275is because the lambdas and method references needed for streams almost always
276result in larger binary size than their loop equivalents (see
277[crbug.com/344943957] for examples).
Andrew Grieve99e388f2023-11-02 20:46:51278
279The `parallel()` and `parallelStream()` APIs are simpler than their loop
Andrew Grieve31928c92024-11-27 21:00:13280equivalents, but are banned due to a lack of a compelling use case in Chrome.
281If you find one, please discuss on `java@chromium.org`.
282
283Use of `stream()` without a lambda / method reference is allowed. E.g.:
284
285```java
286@SuppressWarnings("NoStreams")
287private static List<Integer> boxInts(int[] arr) {
288 return Arrays.stream(arr).boxed().collect(Collectors.toList());
289}
290
291@SuppressWarnings("NoStreams")
292private static List<String> readLines(BufferedReader bufferedReader) {
293 return bufferedReader.lines().collect(Collectors.toList());
294}
295```
Andrew Grieve99e388f2023-11-02 20:46:51296
297[Java streams]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Andrew Grieve31928c92024-11-27 21:00:13298[crbug.com/344943957]: https://crbug.com/344943957
Andrew Grieve99e388f2023-11-02 20:46:51299
300### AndroidX Annotations {#annotations}
301
302* Use them liberally. They are [documented here](https://developer.android.com/studio/write/annotations).
agrieve398286b2018-08-15 01:44:45303 * They generally improve readability.
Andrew Grieve99e388f2023-11-02 20:46:51304 * Many make lint more useful.
Andrew Grieve506d5622025-01-29 21:15:55305* What about `androidx.annotation.Nullable`?
306 * We are migrating away from it (see [nullaway.md]).
307 * Keep using it in files that have not yet been migrated.
agrieve398286b2018-08-15 01:44:45308
Andrew Grieve99e388f2023-11-02 20:46:51309#### IntDefs {#intdefs}
Carlos Knippschildf2e58c12021-06-03 01:43:37310
Andrew Grieve99e388f2023-11-02 20:46:51311Values can be declared outside or inside the `@interface`. Chromium style is
312to declare inside.
Carlos Knippschildf2e58c12021-06-03 01:43:37313
314```java
315@IntDef({ContactsPickerAction.CANCEL, ContactsPickerAction.CONTACTS_SELECTED,
316 ContactsPickerAction.SELECT_ALL, ContactsPickerAction.UNDO_SELECT_ALL})
317@Retention(RetentionPolicy.SOURCE)
318public @interface ContactsPickerAction {
319 int CANCEL = 0;
320 int CONTACTS_SELECTED = 1;
321 int SELECT_ALL = 2;
322 int UNDO_SELECT_ALL = 3;
323 int NUM_ENTRIES = 4;
324}
325// ...
326void onContactsPickerUserAction(@ContactsPickerAction int action, ...);
327```
328
329Values of `Integer` type are also supported, which allows using a sentinel
330`null` if needed.
331
332[@IntDef annotation]: https://developer.android.com/studio/write/annotations#enum-annotations
333[Android lint]: https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/lint.md
334
Andrew Grieve99e388f2023-11-02 20:46:51335
336## Style / Formatting {#style}
nyquistaae4c7c2017-02-15 20:41:42337
agrieve398286b2018-08-15 01:44:45338### File Headers
John Palmerbe051302021-05-19 11:48:35339* Use the same format as in the [C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md#File-headers).
nyquistaae4c7c2017-02-15 20:41:42340
agrieve398286b2018-08-15 01:44:45341### TODOs
Andrew Grieve8d9e40f2023-03-15 21:04:42342
Alison Gale37015772024-06-28 19:47:48343* TODO should follow chromium convention. Examples:
344 * `TODO(username): Some sentence here.`
345 * `TODO(crbug.com/40192027): Even better to use a bug for context.`
nyquistaae4c7c2017-02-15 20:41:42346
Andrew Grieved99e3c02023-10-25 14:56:48347### Parameter Comments
348
349Use [parameter comments] when they aid in the readability of a function call.
350
351E.g.:
352
353```java
354someMethod(/* enabled= */ true, /* target= */ null, defaultValue);
355```
356
357[parameter comments]: https://errorprone.info/bugpattern/ParameterName
358
359### Default Field Initializers
Andrew Grieve8d9e40f2023-03-15 21:04:42360
nyquist9d61f982017-02-10 00:29:08361* Fields should not be explicitly initialized to default values (see
362 [here](https://groups.google.com/a/chromium.org/d/topic/chromium-dev/ylbLOvLs0bs/discussion)).
nyquistaae4c7c2017-02-15 20:41:42363
Andrew Grieve8d9e40f2023-03-15 21:04:42364### Curly Braces
365
nyquistaae4c7c2017-02-15 20:41:42366Conditional braces should be used, but are optional if the conditional and the
367statement can be on a single line.
368
369Do:
370
371```java
372if (someConditional) return false;
373for (int i = 0; i < 10; ++i) callThing(i);
374```
375
376or
377
378```java
379if (someConditional) {
Nate Fischerfc38dc812024-04-24 17:07:26380 return false;
nyquistaae4c7c2017-02-15 20:41:42381}
382```
383
384Do NOT do:
385
386```java
387if (someConditional)
Nate Fischerfc38dc812024-04-24 17:07:26388 return false;
nyquistaae4c7c2017-02-15 20:41:42389```
390
nyquist2d192c4c2017-03-06 21:36:51391### Import Order
Andrew Grieve8d9e40f2023-03-15 21:04:42392
nyquist2d192c4c2017-03-06 21:36:51393* Static imports go before other imports.
394* Each import group must be separated by an empty line.
395
396This is the order of the import groups:
397
3981. android
Yun Liuf40227d92019-04-04 17:37:463991. androidx
nyquist2d192c4c2017-03-06 21:36:514001. com (except com.google.android.apps.chrome)
4011. dalvik
4021. junit
4031. org
4041. com.google.android.apps.chrome
4051. org.chromium
4061. java
4071. javax
408
Andrew Grieve11c370072023-07-18 13:46:46409## Testing
410
411Googlers, see [go/clank-test-strategy](http://go/clank-test-strategy).
412
413In summary:
414
415* Use real dependencies when feasible and fast. Use Mockito’s `@Mock` most
416 of the time, but write fakes for frequently used dependencies.
417
Andrew Grievef8a603ce2024-05-21 20:09:24418* Do not use Robolectric Shadows for Chromium code.
419 * Shadows make code harder to refactor.
420 * Prefer to refactor code to make it more testable.
421 * When you really need to use a test double for a static method, add a
422 `setFooForTesting() [...]` method to make the test contract explicit.
423 * Use [`ResettersForTesting.register()`] from within `ForTesting()`
424 methods to ensure that state is reset between tests.
Andrew Grieve11c370072023-07-18 13:46:46425
426* Use Robolectric when possible (when tests do not require native). Other
427 times, use on-device tests with one of the following annotations:
428 * [`@Batch(UNIT_TESTS)`] for unit tests
429 * [`@Batch(PER_CLASS)`] for integration tests
430 * [`@DoNotBatch`] for when each test method requires an app restart
431
432[`ResettersForTesting.register()`]: https://source.chromium.org/search?q=symbol:ResettersForTesting.register
433[`@Batch(UNIT_TESTS)`]: https://source.chromium.org/search?q=symbol:Batch.UNIT_TESTS
434[`@Batch(PER_CLASS)`]: https://source.chromium.org/search?q=symbol:Batch.PER_CLASS
435[`@DoNotBatch`]: https://source.chromium.org/search?q=symbol:DoNotBatch
436
437### Test-only Code
Andrew Grieve8d9e40f2023-03-15 21:04:42438
Andrew Grieve0872aad2023-06-26 14:16:31439Functions and fields used only for testing should have `ForTesting` as a
440suffix so that:
Caitlin Fischer210cfab2020-05-07 20:04:30441
Andrew Grieve0872aad2023-06-26 14:16:314421. The `android-binary-size` trybot can [ensure they are removed] in
443 non-test optimized builds (by R8).
4442. [`PRESUMBIT.py`] can ensure no calls are made to such methods outside of
445 tests, and
446
447`ForTesting` methods that are `@CalledByNative` should use
448`@CalledByNativeForTesting` instead.
449
450Symbols that are made public (or package-private) for the sake of tests
451should be annotated with [`@VisibleForTesting`]. Android Lint will check
452that calls from non-test code respect the "otherwise" visibility.
453
Andrew Grievee27a4f712023-07-04 15:16:35454Symbols with a `ForTesting` suffix **should not** be annotated with
Andrew Grieve0872aad2023-06-26 14:16:31455`@VisibleForTesting`. While `otherwise=VisibleForTesting.NONE` exists, it
456is redundant given the "ForTesting" suffix and the associated lint check
Andrew Grievee27a4f712023-07-04 15:16:35457is redundant given our trybot check. You should, however, use it for
458test-only constructors.
Andrew Grieve0872aad2023-06-26 14:16:31459
460[ensure they are removed]: /docs/speed/binary_size/android_binary_size_trybot.md#Added-Symbols-named-ForTest
461[`PRESUMBIT.py`]: https://chromium.googlesource.com/chromium/src/+/main/PRESUBMIT.py
462[`@VisibleForTesting`]: https://developer.android.com/reference/androidx/annotation/VisibleForTesting
Sam Maier7452a0d2022-07-20 18:24:35463
nyquist9d61f982017-02-10 00:29:08464## Location
Andrew Grieve8d9e40f2023-03-15 21:04:42465
nyquist9d61f982017-02-10 00:29:08466"Top level directories" are defined as directories with a GN file, such as
John Palmerbe051302021-05-19 11:48:35467[//base](https://chromium.googlesource.com/chromium/src/+/main/base/)
nyquist9d61f982017-02-10 00:29:08468and
John Palmerbe051302021-05-19 11:48:35469[//content](https://chromium.googlesource.com/chromium/src/+/main/content/),
nyquist9d61f982017-02-10 00:29:08470Chromium Java should live in a directory named
471`<top level directory>/android/java`, with a package name
472`org.chromium.<top level directory>`. Each top level directory's Java should
473build into a distinct JAR that honors the abstraction specified in a native
John Palmerbe051302021-05-19 11:48:35474[checkdeps](https://chromium.googlesource.com/chromium/buildtools/+/main/checkdeps/checkdeps.py)
nyquist9d61f982017-02-10 00:29:08475(e.g. `org.chromium.base` does not import `org.chromium.content`). The full
476path of any java file should contain the complete package name.
477
478For example, top level directory `//base` might contain a file named
479`base/android/java/org/chromium/base/Class.java`. This would get compiled into a
480`chromium_base.jar` (final JAR name TBD).
481
482`org.chromium.chrome.browser.foo.Class` would live in
483`chrome/android/java/org/chromium/chrome/browser/foo/Class.java`.
484
485New `<top level directory>/android` directories should have an `OWNERS` file
486much like
John Palmerbe051302021-05-19 11:48:35487[//base/android/OWNERS](https://chromium.googlesource.com/chromium/src/+/main/base/android/OWNERS).
nyquist9d61f982017-02-10 00:29:08488
Andrew Grieve0872aad2023-06-26 14:16:31489## Tools
490
Andrew Grieveec8284602023-10-16 15:53:25491`google-java-format` is used to auto-format Java files. Formatting of its code
492should be accepted in code reviews.
Andrew Grieve0872aad2023-06-26 14:16:31493
494You can run `git cl format` to apply the automatic formatting.
495
Andrew Grieveec8284602023-10-16 15:53:25496Chromium also makes use of several [static analysis] tools.
Andrew Grieve0872aad2023-06-26 14:16:31497
Andrew Grieveec8284602023-10-16 15:53:25498[static analysis]: /build/android/docs/static_analysis.md
Andrew Grieve0872aad2023-06-26 14:16:31499
nyquistaae4c7c2017-02-15 20:41:42500## Miscellany
Andrew Grieve8d9e40f2023-03-15 21:04:42501
nyquistaae4c7c2017-02-15 20:41:42502* Use UTF-8 file encodings and LF line endings.