The Android Developer Challenge is back! Submit your idea before December 2.

アノテーションによるコード検査の改善

Lint などのコード インスペクション ツールは問題の検出やコードの改善に役立ちますが、インスペクション ツールが推論できる範囲は限られています。たとえば、Android リソース ID は、文字列、グラフィック、カラー、その他のリソースタイプの識別に int を使用します。したがって、インスペクション ツールでは、いつ文字列リソースを指定したか、どこでカラーリソースを指定したかはわかりません。つまり、コード インスペクション ツールを使用しても、アプリが適切にレンダリングできなかったり、実行に失敗したりする可能性があります。

アノテーションを使用して、Lint などのコード インスペクション ツールにヒントを提供すると、見落としやすいコードの問題の検出に役立ちます。アノテーションはメタデータタグとして追加されます。これを変数、パラメータ、戻り値に付加することで、メソッドの戻り値、渡されたパラメータ、ローカル変数、フィールドを検査できます。コード インスペクション ツールでアノテーションを使用すると、null ポインタ例外やリソースタイプの競合などの問題を検出できます。

Android は、アノテーション サポート ライブラリを通じて、さまざまなアノテーションをサポートしています。ライブラリにアクセスするには、android.support.annotation パッケージを使用します。

注: モジュールがアノテーション プロセッサに依存している場合、その依存関係を追加するには「annotationProcessor」依存関係構成を使用する必要があります。詳細については、アノテーション プロセッサの依存関係構成を使用するをご覧ください。

プロジェクトにアノテーションを追加する

プロジェクトでアノテーションを有効にするには、ライブラリまたはアプリに support-annotations 依存関係を追加します。追加したすべてのアノテーションは、コード インスペクションまたは lint タスクを実行したときにチェックされます。

Support Annotations ライブラリ依存関係を追加する

Support Annotations ライブラリは、Google の Maven リポジトリで公開されています。Support Anotations ライブラリをプロジェクトに追加するには、build.gradle ファイルの dependencies ブロックに次の行を追加します。

    dependencies {
        implementation 'com.android.support:support-annotations:28.0.0'
    }
    
次に、ツールバーまたは表示された同期通知で、[Sync Now] をクリックします。

アノテーションを独自のライブラリ モジュールで使用すると、そのアノテーションは、Android Archive(AAR)アーティファクトの一部として、XML 形式で annotations.zip ファイルに組み込まれます。support-annotations 依存関係を追加しても、ライブラリのダウンストリーム ユーザーに対して依存関係は適用されません。

注: appcompat ライブラリを使用している場合、support-annotations 依存関係の追加は不要です。appcompat ライブラリはすでにアノテーション ライブラリに依存しているため、アノテーションにアクセスできます。

サポート リポジトリに含まれているアノテーションの一覧については、Support Annotations ライブラリのリファレンスをご覧ください。また、オートコンプリート機能を使用して、import android.support.annotation. ステートメントで使用可能なオプションを表示することもできます。

コード インスペクションを実行する

Android Studio で、アノテーションの検証と自動 Lint チェックを含むコード インスペクションを開始するには、メニューバーから [Analyze] > [Inspect Code] を選択します。Android Studio は、競合メッセージを表示して、コードとアノテーションが競合する潜在的な問題があることを警告し、有効な解決策を提案します。

コマンドラインから lint タスクを実行して、アノテーションを適用することもできます。lint タスクは、継続的インテグレーション サーバーでの問題報告に役立つ場合がありますが、null 可能性アノテーションは適用しない(Android Studio のみが適用する)ことに注意してください。Lint インスペクションの有効化と実行の詳細については、Lint チェックでコードを改善するをご覧ください。

アノテーションが競合すると警告が生成されますが、警告が生成されてもアプリのコンパイルは可能です。

null 可能性アノテーション

特定の変数、パラメータ、または戻り値の null 可能性をチェックするには、@Nullable および @NonNull アノテーションを追加します。@Nullable アノテーションは null 値が許容される変数、パラメータ、戻り値を示し、@NonNull アノテーションは null 値が許容されない変数、パラメータ、戻り値を示します。

たとえば、null 値を含むローカル変数がパラメータとしてメソッドに渡され、そのパラメータに @NonNull アノテーションが付けられていた場合、コードをビルドすると非 null 競合を示す警告が生成されます。一方、@Nullable としてマークされたメソッドの結果を、あらかじめ null かどうかをチェックせずに参照しようとすると、null 可能性警告が生成されます。メソッドを使用するたびに明示的に null チェックを実施する必要がある場合に限り、メソッドの戻り値に @Nullable を使用してください。

以下の例では、@NonNull アノテーションを context および attrs パラメータに付けて、渡されたパラメータ値が null ではないことを確認しています。onCreateView() メソッド自身の戻り値が null でないことも確認しています。Kotlin では、@NonNull アノテーションを使用する必要がないことに注意してください。これは、null が許容されない型を指定すると、生成されたバイトコードにアノテーションが自動的に追加されるためです。

Kotlin

    import android.support.annotation.NonNull
    ...

        /** Add support for inflating the <fragment> tag. **/
        fun onCreateView(
                name: String?,
                context: Context,
                attrs: AttributeSet
        ): View? {
            ...
        }
    ...
    

Java

    import android.support.annotation.NonNull;
    ...

        /** Add support for inflating the <fragment> tag. **/
        @NonNull
        @Override
        public View onCreateView(String name, @NonNull Context context,
          @NonNull AttributeSet attrs) {
          ...
          }
    ...
    

null 可能性分析

Android Studio では、自動的に推論して null 可能性アノテーションをコードに挿入する null 可能性分析がサポートされています。null 可能性分析により、コード内のメソッド階層全体のコントラクトがスキャンされ、次のものが検出されます。

  • null を返すことができる呼び出しメソッド
  • null を返すべきでないメソッド
  • null 値が許容されるフィールド、ローカル変数、パラメータなどの変数
  • null 値が許容されないフィールド、ローカル変数、パラメータなどの変数

この分析を行うと、分析により検出された箇所に、適切な null アノテーションが自動的に挿入されます。

Android Studio で null 可能性分析を実行するには、[Analyze] > [Infer Nullity] を選択します。Android Studio は、コード内の検出された箇所に Android の @Nullable アノテーションと @NonNull アノテーションを挿入します。null 可能性分析を実行した後で、挿入されたアノテーションを検証することをおすすめします。

注: null 可能性アノテーションを追加する際、オートコンプリートは、Android の null アノテーションの代わりに IntelliJ の @Nullable および @NotNull アノテーションを候補として使用し、対応するライブラリを自動インポートすることがあります。ただし、Android Studio の Lint チェッカーは、Android の null アノテーションのみを検索します。アノテーションを検証する際は、プロジェクトで Android の null アノテーションを使用していることを確認してください。これにより、コード インスペクションの際に Lint チェッカーが適切な通知を送ることが可能になります。

リソース アノテーション

Android では、ドローアブル リソースや文字列リソースなどのリソースへの参照は整数として渡されるため、リソースタイプの検証が効力を発揮します。コードに含まれるパラメータが、ドローアブルなどの特定のタイプのリソースを参照すると想定される場合は、想定される参照型 int が渡されます。ただし、実際に参照されるのは、R.string リソースなど、別のタイプのリソースです。

たとえば、以下の例のように、リソース パラメータに R.string 参照が含まれているかどうかをチェックするには、@StringRes アノテーションを追加します。

Kotlin

    abstract fun setTitle(@StringRes resId: Int)
    

Java

    public abstract void setTitle(@StringRes int resId)
    

コード インスペクションの際に、R.string 参照がパラメータに渡されないと、アノテーションによって警告が生成されます。

@DrawableRes@DimenRes@ColorRes@InterpolatorRes など、他のリソースタイプ向けのアノテーションも、同じアノテーション形式で追加することができ、コード インスペクションの際に実行されます。パラメータで複数のリソースタイプをサポートする場合は、1 つのパラメータにこれらのアノテーションを複数指定できます。アノテーション付きのパラメータが、どのタイプの R リソースでもよいことを示すには、@AnyRes を使用します。

@ColorRes を使用してパラメータをカラーリソースとして指定することもできますが、カラー整数(RRGGBB 形式または AARRGGBB 形式)はカラーリソースとして認識されません。パラメータがカラー整数でなければならないことを示すには、@ColorInt アノテーションを使用します。カラー整数ではなく、android.R.color.black などのカラーリソース ID をアノテーション付きメソッドに渡すコードは、ビルドツールにより不適切なコードと判断され、警告が生成されます。

スレッド アノテーション

スレッド アノテーションは、メソッドが特定のタイプのスレッドから呼び出されているかどうかをチェックします。以下のスレッド アノテーションがサポートされています。

注: ビルドツールは @MainThread アノテーションと @UiThread アノテーションを交換可能なものとして扱うので、@MainThread メソッドから @UiThread メソッドを呼び出すことも、その逆も可能です。ただし、異なるスレッドに複数のビューがあるシステムアプリの場合は、UI スレッドがメインスレッドと異なる可能性があります。したがって、アプリのビュー階層に関連付けられているメソッドには @UiThread アノテーションを付け、アプリのライフサイクルに関連付けられているメソッドにのみ @MainThread アノテーションを付ける必要があります。

1 つのクラスに含まれるすべてのメソッドが同じスレッド要件を共有している場合は、そのクラスに単一のスレッド アノテーションを追加することで、クラス内のすべてのメソッドが同じタイプのスレッドから呼び出されるかどうかを検証できます。

一般的に、スレッド アノテーションは、AsyncTask クラスにおけるメソッドのオーバーライドの検証に使用されます。このクラスはバックグラウンド オペレーションを実行し、UI スレッド上でのみ結果を公開するからです。

値制約アノテーション

渡されたパラメータの値を検証するには、@IntRange@FloatRange@Size の各アノテーションを使用します。@IntRange@FloatRange は、ユーザーが誤った範囲を設定している可能性があるパラメータに適用すると、最も効力を発揮します。

@IntRange アノテーションは、int 型または long 型のパラメータ値が、指定された範囲内にあるかどうかを検証します。以下の例では、alpha パラメータに 0 から 255 までの整数値が含まれることを保証しています。

Kotlin

    fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
    

Java

    public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }
    

@FloatRange アノテーションは、float 型または double 型のパラメータ値が、指定された浮動少数点値の範囲内にあるかどうかをチェックします。以下の例では、alpha パラメータに 0.0 から 1.0 までの浮動少数点値が含まれることを保証しています。

Kotlin

    fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
    

Java

    public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
    

@Size アノテーションは、文字列の長さに加えて、コレクションまたは配列のサイズもチェックします。@Size アノテーションでは、以下の性質を検証できます。

  • 最小サイズ(@Size(min=2) など)
  • 最大サイズ(@Size(max=2) など)
  • 正確なサイズ(@Size(2) など)
  • サイズが倍数でなければならない数(@Size(multiple=2) など)

たとえば、@Size(min=1) はコレクションが空でないかをチェックし、@Size(3) は配列に正確に 3 つの値が含まれているかどうかを検証します。以下の例では、location 配列に 1 つ以上の要素が含まれることを保証しています。

Kotlin

    fun getLocation(button: View, @Size(min=1) location: IntArray) {
        button.getLocationOnScreen(location)
    }
    

Java

    void getLocation(View button, @Size(min=1) int[] location) {
        button.getLocationOnScreen(location);
    }
    

権限アノテーション

メソッドの呼び出し元の権限を検証するには、@RequiresPermission アノテーションを使用します。有効な権限のリストのうち、いずれか 1 つの権限があるかどうかをチェックするには、anyOf 属性を使用します。権限のセットがあるかどうかをチェックするには、allOf 属性を使用します。以下の例では、setWallpaper() メソッドにアノテーションを付けて、このメソッドの呼び出し元に permission.SET_WALLPAPERS 権限があることを保証しています。

Kotlin

    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    @Throws(IOException::class)
    abstract fun setWallpaper(bitmap: Bitmap)
    

Java

    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    public abstract void setWallpaper(Bitmap bitmap) throws IOException;
    

この例では、copyFile() メソッドの呼び出し元に、外部ストレージへの読み取り権限と書き込み権限の両方が付与されていることを要求しています。

Kotlin

    @RequiresPermission(allOf = [
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ])
    fun copyFile(dest: String, source: String) {
        ...
    }

Java

    @RequiresPermission(allOf = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE})
    public static final void copyFile(String dest, String source) {
        //...
    }
    

インテントの権限の場合、インテント アクション名を定義する文字列フィールドに権限要件を指定します。

Kotlin

    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
    const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
    

Java

    @RequiresPermission(android.Manifest.permission.BLUETOOTH)
    public static final String ACTION_REQUEST_DISCOVERABLE =
                "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
    

読み取りアクセスと書き込みアクセスに別々の権限を必要とするコンテンツ プロバイダの権限の場合は、@RequiresPermission.Read または @RequiresPermission.Write アノテーションに、それぞれの権限要件を指定します。

Kotlin

    @RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
    

Java

    @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
    

間接権限

権限がメソッドのパラメータに渡される特定の値に依存している場合は、特定の権限をリストせずに、パラメータ自体に @RequiresPermission を使用します。たとえば、以下の startActivity(Intent) メソッドでは、このメソッドに渡されるインテントに間接権限を使用しています。

Kotlin

    abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
    

Java

    public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)
    

間接権限を使用した場合、ビルドツールはデータフロー分析を実行して、メソッドに渡された引数に @RequiresPermission アノテーションがあるかどうかをチェックします。次に、パラメータの既存のアノテーションをメソッド自体に適用します。startActivity(Intent) の例では、適切な権限のないインテントがメソッドに渡されると、Intent クラスのアノテーションによって、startActivity(Intent) の使用が無効であることを示す警告が生成されます(図 1 を参照)。

図 1. startActivity(Intent) メソッドの間接権限アノテーションにより生成された警告

ビルドツールは、Intent クラスの対応するインテント アクション名のアノテーションから、startActivity(Intent) に関する警告を生成します。

Kotlin

    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    @RequiresPermission(Manifest.permission.CALL_PHONE)
    const val ACTION_CALL = "android.intent.action.CALL"
    

Java

    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    @RequiresPermission(Manifest.permission.CALL_PHONE)
    public static final String ACTION_CALL = "android.intent.action.CALL";
    

メソッドのパラメータにアノテーションを付ける場合、必要に応じて @RequiresPermission を、@RequiresPermission.Read および / または @RequiresPermission.Write の代わりに使用できます。ただし、間接権限では、@RequiresPermission は読み取り権限アノテーションと書き込み権限アノテーションのどちらとも併用できません。

戻り値アノテーション

メソッドの結果(戻り値)が実際に使用されているかどうかを検証するには、@CheckResult アノテーションを使用します。すべての非 void メソッドに @CheckResult アノテーションを付けるのではなく、紛らわしいメソッドの結果を明確にするためにアノテーションを追加します。たとえば、経験の浅い Java デベロッパーは、<String>.trim() が元の文字列から空白を削除すると勘違いしていることがあります。メソッドに @CheckResult アノテーションを付けると、呼び出し元が <String>.trim() メソッドの戻り値を一切使用していない場合に警告が生成されます。

以下の例では、checkPermissions() メソッドにアノテーションを付けて、メソッドの戻り値が実際に参照されることを保証しています。また、デベロッパーに候補として提示する代用メソッドとして enforcePermission() メソッドを指定しています。

Kotlin

    @CheckResult(suggest = "#enforcePermission(String,int,int,String)")
    abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
    

Java

    @CheckResult(suggest="#enforcePermission(String,int,int,String)")
    public abstract int checkPermission(@NonNull String permission, int pid, int uid);
    

CallSuper アノテーション

オーバーライドする側のメソッドがメソッドの super 実装を呼び出しているかどうかを検証するには、@CallSuper アノテーションを使用します。以下の例では、onCreate() メソッドにアノテーションを付けて、オーバーライド側のメソッドの実装が super.onCreate() を呼び出すことを保証しています。

Kotlin

    @CallSuper
    override fun onCreate(savedInstanceState: Bundle?) {
    }
    

Java

    @CallSuper
    protected void onCreate(Bundle savedInstanceState) {
    }
    

Typedef アノテーション

整数および文字列セットの列挙型アノテーションを作成して他の型のコード参照を検証するには、@IntDef アノテーションと @StringDef アノテーションを使用します。Typedef アノテーションは、特定のパラメータ、戻り値、またはフィールドが特定の定数のセットを参照することを保証します。さらに、コード補完により、使用できる定数が自動的に提示されるようになります。

Typedef アノテーションは、@interface を使用して列挙型のアノテーション タイプを新たに宣言します。@IntDef アノテーションおよび @StringDef アノテーションを @Retention と一緒に使用すると、新しいアノテーションを付けることができます。これらのアノテーションは列挙型を定義するために必要です。@Retention(RetentionPolicy.SOURCE) アノテーションは、列挙型アノテーションのデータを .class ファイルに保存しないようコンパイラに通知します。

以下の例は、メソッド パラメータとして渡される値が、定義済みの定数のいずれか 1 つを参照することを保証するアノテーションを作成する方法を示しています。

Kotlin

    import android.support.annotation.IntDef
    //...
    // Define the list of accepted constants and declare the NavigationMode annotation
    @Retention(AnnotationRetention.SOURCE)
    @IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS)
    annotation class NavigationMode

    // Declare the constants
    const val NAVIGATION_MODE_STANDARD = 0
    const val NAVIGATION_MODE_LIST = 1
    const val NAVIGATION_MODE_TABS = 2

    abstract class ActionBar {

        // Decorate the target methods with the annotation
        // Attach the annotation
        @get:NavigationMode
        @setparam:NavigationMode
        abstract var navigationMode: Int

    }
    

Java

    import android.support.annotation.IntDef;
    //...
    public abstract class ActionBar {
        //...
        // Define the list of accepted constants and declare the NavigationMode annotation
        @Retention(RetentionPolicy.SOURCE)
        @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
        public @interface NavigationMode {}

        // Declare the constants
        public static final int NAVIGATION_MODE_STANDARD = 0;
        public static final int NAVIGATION_MODE_LIST = 1;
        public static final int NAVIGATION_MODE_TABS = 2;

        // Decorate the target methods with the annotation
        @NavigationMode
        public abstract int getNavigationMode();

        // Attach the annotation
        public abstract void setNavigationMode(@NavigationMode int mode);
    }
    

このコードをビルドすると、mode パラメータが定義済みの定数(NAVIGATION_MODE_STANDARDNAVIGATION_MODE_LISTNAVIGATION_MODE_TABS)のいずれも参照していない場合、警告が生成されます。

また、@IntDef@IntRange を組み合わせると、整数が指定された定数セットまたは範囲内の値になることを明示できます。

フラグによる定数の結合を有効にする

使用できる定数をユーザーがフラグ(|&^ など)で結合できる場合、flag 属性を使用したアノテーションを定義して、パラメータまたは戻り値が有効なパターンを参照しているかどうかをチェックできます。以下の例では、有効な DISPLAY_ 定数のリストを使用した DisplayOptions アノテーションを作成しています。

Kotlin

    import android.support.annotation.IntDef
    ...

    @IntDef(flag = true, value = [
        DISPLAY_USE_LOGO,
        DISPLAY_SHOW_HOME,
        DISPLAY_HOME_AS_UP,
        DISPLAY_SHOW_TITLE,
        DISPLAY_SHOW_CUSTOM
    ])
    @Retention(AnnotationRetention.SOURCE)
    annotation class DisplayOptions
    ...
    

Java

    import android.support.annotation.IntDef;
    ...

    @IntDef(flag=true, value={
            DISPLAY_USE_LOGO,
            DISPLAY_SHOW_HOME,
            DISPLAY_HOME_AS_UP,
            DISPLAY_SHOW_TITLE,
            DISPLAY_SHOW_CUSTOM
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface DisplayOptions {}

    ...
    

アノテーション フラグを使用したコードをビルドすると、修飾パラメータまたは戻り値が有効なパターンを参照していない場合、警告が生成されます。

Keep アノテーション

@Keep アノテーションを使用すると、ビルド時にコードが圧縮されても、アノテーション付きのクラスやメソッドは削除されません。通常、このアノテーションはリフレクションを介してアクセスされるメソッドとクラスに付加され、コンパイラがコードを未使用と判断するのを防ぎます。

注意: @Keep アノテーションを付けたクラスとメソッドは、アプリのロジック内で参照されていなくても、常にアプリの APK に組み込まれます。

アプリのサイズを小さいままにするには、アプリ内の個々の @Keep アノテーションを保持する必要があるかどうかを検討します。リフレクションを使用してアノテーション付きのクラスやメソッドにアクセスする場合は、ProGuard ルールで -if 条件を使用し、リフレクション呼び出しを行うクラスを指定します。

コードを圧縮し、削除すべきでないコードを指定する方法の詳細については、コードとリソースを圧縮するをご覧ください。

コード可視性アノテーション

メソッド、クラス、フィールド、パッケージなど、コードの特定の部分の可視性を示すには、次のアノテーションを使用します。

テスト用に表示する

@VisibleForTesting アノテーションは、コードをテストしやすくするために、アノテーション付きのメソッドの可視性を通常必要なレベルより高めていることを示します。このアノテーションにはオプションの otherwise 引数があり、テスト用にメソッドを表示する必要がない場合の可視性を指定できます。Lint は、otherwise 引数を使用して、本来意図されている可視性を適用します。

以下の例で、myMethod() は通常は private ですが、テスト用としては package-private です。次の VisibleForTesting.PRIVATE 指定により、このメソッドが private アクセスで許可されているコンテキストの外部(別のコンパイル単位など)から呼び出されると、Lint はメッセージを表示します。

Kotlin

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    fun myMethod() {
        ...
    }
    

Java

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    void myMethod() { ... }
    

メソッドがテストのためだけに存在することを示すために、@VisibleForTesting(otherwise = VisibleForTesting.NONE) を指定することもできます。この形式は @RestrictTo(TESTS) を使用する場合と同じです。これらは両方とも同じ Lint チェックを実行します。

API を制限する

@RestrictTo アノテーションは、アノテーション付き API(パッケージ、クラス、またはメソッド)へのアクセスが次のように制限されていることを示します。

サブクラス

アノテーション フォーム @RestrictTo(RestrictTo.Scope.SUBCLASSES) は、API アクセスをサブクラスのみに制限します。

この場合、この API にアクセスできるのは、アノテーション付きクラスを拡張するクラスだけです。Java の protected 修飾子は、同じパッケージ内の無関係なクラスからのアクセスを許可するため、制限が十分ではありません。また、前に protected されてオーバーライドされたメソッド public は二度と作成できないため、将来の柔軟性を確保するためにメソッド public を残したいが、クラスがクラス内またはサブクラスからの使用のみを目的としているというヒントを提供したい場合もあります。

ライブラリ

アノテーション フォーム @RestrictTo(RestrictTo.Scope.GROUP_ID) は、API アクセスを自分のライブラリのみに制限します。

この場合、アノテーション付き API にアクセスできるのは、自分のライブラリ コードだけです。これにより、希望するパッケージ階層にコードを整理できるだけでなく、関連ライブラリのグループ間でコードを共有することもできます。このオプションは、外部使用を目的としない実装コードを多数含むサポート ライブラリではすでに利用可能ですが、さまざまな補助サポート ライブラリ間で共有するには public であることが必要です。

注: Android サポート ライブラリのクラスとパッケージには、現在 @RestrictTo(GROUP_ID) アノテーションが付けられています。そのため、誤ってこれらの実装クラスを使用すると、Lint により使用しないよう警告されます。

テスト

アノテーション フォーム @RestrictTo(RestrictTo.Scope.TESTS) を使用すると、他のデベロッパーが自分のテスト API にアクセスすることを防止できます。

この場合、アノテーション付き API にアクセスできるのは、テストコードだけです。これにより、テストのみを目的とする開発用 API を他のデベロッパーが使用するのを防ぐことができます。