## Classes [CL] <a name="classes"></a>

These are rules about classes, interfaces, and inheritance.

### Inherit new public classes from the appropriate base class <a name="classes-inheritance"></a>

Inheritance exposes API in your subclass which may not be appropriate. For
example, a new public subclass of `FrameLayout` will look like a `FrameLayout`
(plus the new functionality/API). If that inherited API is not appropriate for
your use case, inherit from something further up the tree (for example,
`ViewGroup` or even `View`, instead of `FrameLayout`).

If you are tempted to override methods from the base class to throw
`UnsupportedOperationException`, reconsider which base class you are using.

### Use the base collections classes <a name="classes-collections"></a>

Whether taking a collection as an argument or returning it as a value, always
prefer the base class over the specific implementation (e.g. return `List<Foo>`
rather than `ArrayList<Foo>`).

Use a base class that expresses appropriate constraints for the API. For
example, an API whose collection must be ordered should use `List` and an API
whose collection must consist of unique elements should use `Set`.

In Kotlin, prefer immutable collections. See
[Collection mutability](#methods-collections-mutability) for more details.

### Abstract classes versus interfaces <a name="classes-interfaces"></a>

Java 8 adds support for default interface methods, which allows API designers to
add methods to interfaces while maintaining binary compatibility. Platform code
and all Jetpack libraries should target Java 8 or later.

In cases where the default implementation is stateless, API designers *should*
prefer interfaces over abstract classes -- that is, default interface methods
can be implemented as calls to other interface methods.

In cases where a constructor or internal state is required by the default
implementation, abstract classes *must* be used.

In both cases, API designers may choose to leave a single method abstract to
simplify usage as a lambda.

```java {.good .no-copy}
public interface AnimationEndCallback {
  // Always called, must be implemented.
  public void onFinished(Animation anim);
  // Optional callbacks.
  public default void onStopped(Animation anim) { }
  public default void onCanceled(Animation anim) { }
}
```

### Class names should reflect what they extend <a name="classes-subclass-naming"></a>

For example, classes which extend `Service` should be named `FooService` for
clarity.

```java {.bad .no-copy}
public class IntentHelper extends Service {}
```

```java {.good .no-copy}
public class IntentService extends Service {}
```

#### Generic suffixes (`Helper`, `Util`, etc.) <a name="classes-generic-naming"></a>

Avoid using generic class name suffixes like `Helper` and `Util` for collections
of utility methods. Instead, put the methods directly in the associated classes
or into Kotlin extension functions.

In cases where methods are bridging multiple classes, give the containing class
a meaningful name that explains what it does.

In *very* limited cases, using the `Helper` suffix may be appropriate:

-   Used for composition of default behavior
-   May involve delegation of existing behavior to new classes
-   May require persisted state
-   Typically involves `View`

For example, if backporting tooltips requires persisting state associated with a
`View` and calling several methods on the `View` to install the backport,
`TooltipHelper` would be an acceptable class name.

### Do not expose AIDL-generated code as public APIs directly <a name="classes-wrap-aidl"></a>

Keep AIDL-generated code as implementation details. Generated AIDL classes do
not meet the API style guide requirements (for example, they cannot use
overloading) and are not guaranteed to maintain language API compatibility, so
we can't embed them in a public API.

Instead, add a public API layer on top of the AIDL interface, even if it
initially is a shallow wrapper.

#### `Binder` interfaces <a name="classes-wrap-binder"></a>

If the `Binder` interface is an implementation detail, it can be changed freely
in the future, with the public layer allowing for the required backward
compatibility to be maintained. For example, you may find you need to add new
arguments to the internal calls, or optimize IPC traffic via batching/streaming,
using shared memory, or similar. None of these can currently be done if your
AIDL interface is also the public API.

For example, instead of exposing `FooService` as a public API directly:

```java {.bad .no-copy}
// BAD: Public API generated from IFooService.aidl
public class IFooService {
   public void doFoo(String foo);
}
```

instead wrap the `Binder` interface inside a manager or other class:

```java {.good .no-copy}
/**
 * @hide
 */
public class IFooService {
   public void doFoo(String foo);
}

public IFooManager {
   public void doFoo(String foo) {
      mFooService.doFoo(foo);
   }
}
```

and if later a new argument is needed for this call, the internal interface can
be kept simple and convenient overloads added to the public API. And the
wrapping layer can be used to handle other backwards-compatibility concerns as
the implementation evolves, as well:

```java {.good .no-copy}
/**
 * @hide
 */
public class IFooService {
   public void doFoo(String foo, int flags);
}

public IFooManager {
   public void doFoo(String foo) {
      if (mAppTargetSdkLevel < 26) {
         useOldFooLogic(); // Apps targeting API before 26 are broken otherwise
         mFooService.doFoo(foo, FLAG_THAT_ONE_WEIRD_HACK);
      } else {
         mFooService.doFoo(foo, 0);
      }
   }

   public void doFoo(String foo, int flags) {
      mFooService.doFoo(foo, flags);
   }
}
```

For `Binder` interfaces that are not part of the Android platform (for example,
a service interface exported by Google Play Services for applications to use),
the requirement for a stable, published, and versioned IPC interface means that
it is much harder to evolve the interface itself. However, it is still
worthwhile to have a wrapper layer around it, to match other API guidelines and
to make it easier to use the same public API for a new version of the IPC
interface, if that ever becomes necessary.

#### Do not use raw `Binder` objects in public API <a name="classes-wrap-binder"></a>

A `Binder` object does not have any meaning on its own and thus should not be
used in public API. One common use-case is to use a `Binder` or `IBinder` as a
token because it has identity semantics. Instead of using a raw `Binder` object
use a wrapper token class instead.

```java {.bad .no-copy}
public final class IdentifiableObject {
  public Binder getToken() {...}
}
```

```java {.good .no-copy}
public final class IdentifiableObjectToken {
  /**
   * @hide
   */
  public Binder getRawValue() {...}

  /**
   * @hide
   */
  public static IdentifiableObjectToken wrapToken(Binder rawValue) {...}
}

public final class IdentifiableObject {
  public IdentifiableObjectToken getToken() {...}
}
```

### `Manager` classes must be `final`.

Manager classes should be declared as `final`. Manager classes talk to system
services and are the single point of interaction. There is no need for
customization so declare it as `final`.

### Do not use `CompletableFuture` or `Future` <a name="classes-avoid-future"></a>

`java.util.concurrent.CompletableFuture` has a large API surface that permits
arbitrary mutation of the future's value and has error-prone defaults
.

Conversely, `java.util.concurrent.Future` is missing non-blocking listening,
making it hard to use with asynchronous code.

In **platform code**, prefer a combination of a completion callback, `Executor`,
and if the API supports cancellation `CancellationSignal`.

```java {.good .no-copy}
public void asyncLoadFoo(android.os.CancellationSignal cancellationSignal,
    Executor callbackExecutor,
    android.os.OutcomeReceiver<FooResult, Throwable> callback);
```

In **libraries and apps**, prefer Guava's `ListenableFuture`.

```java {.good .no-copy}
public com.google.common.util.concurrent.ListenableFuture<Foo> asyncLoadFoo();
```

If you are **targeting Kotlin**, prefer `suspend` functions.

```kotlin {.good .no-copy}
suspend fun asyncLoadFoo(): Foo
```

### Do not use `Optional` <a name="classes-avoid-optional"></a>

While `Optional` can have advantages in some API surfaces, it is inconsistent
with the existing Android API surface area. `@Nullable` and `@NonNull` provide
tooling assistance for `null` safety and Kotlin enforces nullability contracts
at the compiler level, making `Optional` unnecessary.

For optional primitives, use paired `has` and `get` methods. If the value isn't
set (i.e., `has` returns `false`), the `get` method should throw an
`IllegalStateException`.

```java {.good .no-copy}
public boolean hasAzimuth() { ... }
public int getAzimuth() {
  if (!hasAzimuth()) {
    throw new IllegalStateException("azimuth is not set");
  }
  return azimuth;
}
```

### Use private constructors for non-instantiable classes <a name="classes-non-instantiable"></a>

Classes that can only be created by `Builder`s, classes containing only
constants or static methods, or otherwise non-instantiable classes should
include at least one private constructor to prevent instantiation via the
default no-arg constructor.

```java {.good .no-copy}
public final class Log {
  // Not instantiable.
  private Log() {}
}
```

### Singletons <a name="classes-singleton"></a>

Singleton are discouraged because they have the following testing-related
drawbacks:

1.  Construction is managed by the class, preventing the use of fakes
1.  Tests cannot be hermetic due to the static nature of a singleton
1.  To work around these issues, developers either have to know the internal
    details of the singleton or create a wrapper around it

Prefer the [single instance](#classes-single-instance) pattern, which relies on
an abstract base class to address these issues.

### Single instance {#classes-single-instance}

Single instance classes use an abstract base class with a `private` or
`internal` constructor and provide a static `getInstance()` method to obtain an
instance. The `getInstance()` method **must** return the same object on
subsequent calls.

The object returned by `getInstance()` should be a private implementation of the
abstract base class.

```kotlin {.bad .no-copy}
class Singleton private constructor(...) {
  companion object {
    private val _instance: Singleton by lazy { Singleton(...) }

    fun getInstance(): Singleton {
      return _instance
    }
  }
}
```

```kotlin {.good .no-copy}
abstract class SingleInstance private constructor(...) {
  companion object {
    private val _instance: SingleInstance by lazy { SingleInstanceImp(...) }
    fun getInstance(): SingleInstance {
      return _instance
    }
  }
}
```

Single instance differs from [singleton](#classes-singleton) in that developers
can create a fake version of `SingleInstance` and use their own Dependency
Injection framework to manage the implementation without having to create a
wrapper, or the library can provide its own fake in a `-testing` artifact.

### Classes that release resources should implement `AutoCloseable` <a name="classes-autocloseable"></a>

Classes that release resources through `close`, `release`, `destroy` or similar
methods should implement `java.lang.AutoCloseable` to allow developers to
automatically clean up these resources when using a `try-with-resources` block.

### Avoid introducing new View subclasses in android.* <a name="classes-no-new-framework-views"></a>

Do not introduce new classes that inherit directly or indirectly from
`android.view.View` in the platform public API (i.e. in `android.*`).

Android's UI toolkit is now [Compose-first](https://d.android.com/compose). New
UI functionality exposed by the platform should be exposed as lower-level APIs
that can be used to implement Jetpack Compose and optionally View-based UI
components for developers in [androidx](http://go/androidx) libraries. Offering
these components in androidx libraries affords opportunities for backported
implementations when platform functionality is not available.

## Fields [F] <a name="fields"></a>

These rules are about public fields on classes.

### Do not expose raw fields <a name="fields-avoid-raw"></a>

Java classes should not expose fields directly. Fields should be private and
accessible only via public getters and setters regardless of whether these
fields are final or non-final.

Rare exceptions include simple data structures where there will never be a need
to enhance the functionality of specifying or retrieving a field. In such cases,
the fields should be named using standard variable naming conventions, ex.
`Point.x` and `Point.y`.

Kotlin classes may expose properties.

### Exposed fields should be marked final <a name="fields-mutable-bare"></a>

Raw fields are strongly discouraged (@see
[Do not expose raw fields](#fields-avoid-raw)). But in the rare situation where
a field is exposed as a public field, mark that field `final`.

### Internal fields should not be exposed <a name="fields-internal"></a>

Do not reference internal field names in public API.

```java {.bad .no-copy}
public int mFlags;
```

### Use `public` instead of `protected` <a name="fields-public"></a>

@see [Use public instead of protected](#avoid-protected)

## Constants [C] <a name="constants"></a>

These are rules about public constants.

### Flag constants should be non-overlapping `int` or `long` values <a name="constants-flags"></a>

“Flags” implies bits that can be combined into some union value. If this is not
the case, do not call the variable/constant `flag`.

```java {.bad .no-copy}
public static final int FLAG_SOMETHING = 2;
public static final int FLAG_SOMETHING = 3;
```

```java {.good .no-copy}
public static final int FLAG_PRIVATE = 1 << 2;
public static final int FLAG_PRESENTATION = 1 << 3;
```

See [`@IntDef` for bitmask flags](#annotations-intdef-bitmask) for more
information on defining public flag constants.

### `static final` constants should use all-cap, underscore-separated naming convention <a name="constants-naming"></a>

All words in the constant should be capitalized and multiple words should be
separated by `_`. For example:

```java {.bad .no-copy}
public static final int fooThing = 5
```

```java {.good .no-copy}
public static final int FOO_THING = 5
```

### Use standard prefixes for constants <a name="constants-prefixes"></a>

Many of the constants used in Android are for standard things, such as flags,
keys, and actions. These constants should have standard prefixes to make them
more identifiable as these things.

For example, intent extras should start with `EXTRA_`. Intent actions should
start with `ACTION_`. Constants used with `Context.bindService()` should start
with `BIND_`.

### Naming and scoping of key constants <a name="constants-keys"></a>

String constant values should be consistent with the constant name itself, and
should generally be scoped to the package or domain. For example:

```java {.bad .no-copy}
public static final String FOO_THING = “foo”
```

is neither named consistently nor appropriately scoped. Instead, consider:

```java {.good .no-copy}
public static final String FOO_THING = “android.fooservice.FOO_THING”
```

Prefixes of `android` in scoped string constants are reserved for the Android
Open Source Project.

Intent actions and extras, as well as Bundle entries, should be namespaced using
the package name they are defined within.

```java {.good .no-copy}
package android.foo.bar {
  public static final String ACTION_BAZ = “android.foo.bar.action.BAZ”
  public static final String EXTRA_BAZ = “android.foo.bar.extra.BAZ”
}
```

### Use `public` instead of `protected` <a name="constants-visibility"></a>

@see [Use public instead of protected](#avoid-protected)

### Use consistent prefixes <a name="constants-consistency"></a>

Related constants should all start with the same prefix. For example, for a set
of constants to use with flag values:

```java {.bad .no-copy}
public static final int SOME_VALUE = 0x01;

public static final int SOME_OTHER_VALUE = 0x10;

public static final int SOME_THIRD_VALUE = 0x100;
```

```java {.good .no-copy}
public static final int FLAG_SOME_VALUE = 0x01;

public static final int FLAG_SOME_OTHER_VALUE = 0x10;

public static final int FLAG_SOME_THIRD_VALUE = 0x100;
```

@see [Use standard prefixes for constants](#constants-prefixes)

### Use consistent resource names <a name="constants-resource-names"></a>

Public identifiers, attributes, and values *must* be named using the camelCase
naming convention, e.g. `@id/accessibilityActionPageUp` or
`@attr/textAppearance`, similar to public fields in Java.

In some cases, a public identifier or attribute may include a common prefix
separated by an underscore:

*   Platform config values such as `@string/config_recentsComponentName` in
    [config.xml](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/res/res/values/config.xml;l=2721;drc=60faefffe98cb30abad690ccd183ef858bb7d3eb)
*   Layout-specific view attributes such as `@attr/layout_marginStart` in
    [attrs.xml](https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/res/res/values/attrs.xml;l=3446;drc=60faefffe98cb30abad690ccd183ef858bb7d3eb)

Public themes and styles *must* follow the hierarchical PascalCase naming
convention, e.g. `@style/Theme.Material.Light.DarkActionBar` or
`@style/Widget.Material.SearchView.ActionBar`, similar to nested classes in
Java.

Layout and drawable resources *should not* be exposed as public APIs. If they
must be exposed, however, then public layouts and drawables *must* be named
using the under_score naming convention, e.g. `layout/simple_list_item_1.xml` or
`drawable/title_bar_tall.xml`.

### When constants could change, make them dynamic <a name="constants-min-max"></a>

Constant values may be inlined at compile time, so keeping values the same is
considered part of the API contract. If the value of a `MIN_FOO` or `MAX_FOO`
constant could change in the future, consider making them dynamic methods
instead.

```java {.bad .no-copy}
CameraManager.MAX_CAMERAS
```

```java {.good .no-copy}
CameraManager.getMaxCameras()
```

### Consider forward-compatibility for callbacks <a name="constants-callbacks-compatibility"></a>

Constants defined in future API versions are not known to apps that target older
APIs. For this reason, constants delivered to apps should take into
consideration that app’s target API version and map newer constants to a
consistent value. Consider the following scenario:

Hypothetical SDK source:

```java {.no-copy}
// Added in API level 22
public static final int STATUS_SUCCESS = 1;
public static final int STATUS_FAILURE = 2;
// Added in API level 23
public static final int STATUS_FAILURE_RETRY = 3;
// Added in API level 26
public static final int STATUS_FAILURE_ABORT = 4;
```

Hypothetical app with `targetSdkVersion="22"`:

```java {.no-copy}
if (result == STATUS_FAILURE) {
  // Oh no!
} else {
  // Success!
}
```

In this case, the app was designed within the constraints of API level 22 and
made a (somewhat) reasonable assumption that there were only two possible
states. If the app receives the newly-added `STATUS_FAILURE_RETRY`, however, it
will interpret this as success.

Methods that return constants can safely handle cases like this by constraining
their output to match the API level targeted by the app:

```java {.good .no-copy}
private int mapResultForTargetSdk(Context context, int result) {
  int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
  if (targetSdkVersion < 26) {
    if (result == STATUS_FAILURE_ABORT) {
      return STATUS_FAILURE;
    }
    if (targetSdkVersion < 23) {
      if (result == STATUS_FAILURE_RETRY) {
        return STATUS_FAILURE;
      }
    }
  }
  return result;
}
```

It’s unreasonable to expect developers and their published applications to be
clairvoyant. If you define an API with an `UNKNOWN` or `UNSPECIFIED` constant
that looks like a catch-all, developers will assume that the published constants
when they wrote their app are exhaustive. If you’re unwilling to set this
expectation, reconsider whether a catch-all constant is a good idea for your
API.

Consider also that libraries cannot specify their own `targetSdkVersion`
separate from the app, and that handling `targetSdkVersion` behavior changes
from library code is exceedingly complicated and error-prone.

### Integer or `String` constant? <a name="constants-integer-or-string"></a>

Use integer constants and `@IntDef` if the namespace for values is not
extensible outside of your package. Use string constants if the namespace is
shared or can be extended by code outside of your package.

### Data classes <a name="data-class"></a>

Data classes represent a set of immutable properties and provide a small and
well-defined set of utility functions for interacting with that data.

**Do not** use `data class` in public Kotlin APIs, as the Kotlin compiler does
not guarantee language API or binary compatibility for generated code. Instead,
manually implement the required functions.

#### Instantiation <a name="data-class-new"></a>

In Java, data classes should provide a constructor when there are few properties
or use the [`Builder`](#builders) pattern when there are many properties.

In Kotlin, data classes should provide a constructor with default arguments
regardless of the number of properties. Data classes defined in Kotlin may also
benefit from providing a builder when targeting Java clients.

#### Modification and copying <a name="data-class-copy"></a>

In cases where data needs to be modified, provide either a
[`Builder`](#builders) with a copy constructor (Java) or a `copy()` member
function (Kotlin) that returns a new object.

When providing a `copy()` function in Kotlin, arguments must match the class's
constructor and defaults must be populated using the object's current values.

```kotlin {.good .no-copy}
class Typography(
  val labelMedium: TextStyle = TypographyTokens.LabelMedium,
  val labelSmall: TextStyle = TypographyTokens.LabelSmall
) {
    fun copy(
      labelMedium: TextStyle = this.labelMedium,
      labelSmall: TextStyle = this.labelSmall
    ): Typography = Typography(
      labelMedium = labelMedium,
      labelSmall = labelSmall
    )
}
```

#### Additional functionality <a name="data-class-misc"></a>

Data classes should implement both
[`equals()` and `hashCode()`](#equals-and-hashcode), and every property must be
accounted for in the implementations of these methods.

Data classes may implement [`toString()`](#toString) with a recommended format
matching [Kotlin's data class](https://kotlinlang.org/docs/data-classes.html)
implementation, e.g. `User(var1=Alex, var2=42)`.
