web-dev-qa-db-ja.com

Android @ NonNullの有用性

いくつか読んで質問した後 このように _@NonNull_ Androidサポートアノテーションを使用することに意味があるかどうか疑問に思いました。

Android Studioから非常に小さな警告が表示されますが、nullパラメータで@ NonNullとして注釈が付けられます。警告のみですか?

ユニットテストはどうですか? nullパラメータを使用してメソッドをテストする必要がありますか?実行すると... NullPointerExceptionとテストは失敗します

私たちが2人の開発者だとしましょう。 1つはAPIに取り組んでおり、もう1つはあらゆる種類の方法でAPIをテストしています。 2番目の開発者として、APIが防弾になるようにすべてをテストするのは私の責任です。これが単体テストの要点ですよね?

それでは... @ NonNullを使用する最初の開発者のポイントは何ですか?

他の誰かがこのAPIをnullパラメータで使用すると... APIは[〜#〜] npe [〜#〜]をスローします。それから彼は考えます:「Urg、そのAPIはうんざりです... NPE!」そして彼は正しいでしょう。彼が送信したパラメーターがnullかどうかをチェックしないためのいたずらな開発者は、IllegalArgumentExceptionに直面する必要があります。これは、APIのせいではないためです。

私が間違っている ?

これらのアノテーションは、コンパイラーにattempting to call methodName(@NonNull Object object) with null parameterのようなエラーを表示させると思いました。

アップデート1

コメントありがとうございます。私がここで直面している「問題」について、可能であれば要約したいと思います。抽象的な方法で。

機能を提供するパブリックメソッドでラップされたプライベート内部コードを使用して、いくつかのコード(API、ライブラリ、クラスなど)を記述します。

これらのパブリックメソッドは、(私を含めて)他の誰かが使用することを想定しています。それらのいくつかは、決してnullであってはならない引数を取ります。さもないと、すべての地獄が解き放たれます。

あなたのコメントを読んで、私は次のオプションに直面しています:

  1. Java _@NonNull_を規定するドキュメント)でサポートされているコントラクト/アノテーション(_parameter must not be null_)を引き続き使用します。nullパラメータをチェックしないでください(または、IDE警告が表示されます)そして、どういうわけか、nullパラメータを受信しないように祈ります。
  2. 上記と同じですが、nullチェックを強制し(IDEは_condition will always be false_を警告しますが)、nullを受け取った場合にNPEを発生させる代わりにIllegalArgumentExceptionをスローします)パラメータ;
  3. コントラクト/アノテーションの使用を停止し、Java Docを使用して他の開発者に警告し、すべてのパラメーターの手動チェックを追加します。

最後に、単体テストの場合...防弾コードを使用できないことはわかっていますが、コードからの予期しない動作を防ぎ、プロセスを検証するために、コードを可能な限り「モンキーテスト」するのが好きです(ユニットテストのベースで、私は信じています)-

21
Mackovich

その主な目的は、同僚に情報を提供することです。大規模なプロジェクトのプログラマーは、1人だけではありません。 NotNullを使用すると、関数のコントラクトはnullを送信できないことを意味するため、他のプログラマーはそれを実行しません。そうでなければ、setFoo(null)を呼び出すとFooがクリアされるのに対し、APIはFooがないことを処理できないという論理的な仮定を立てることができます。

10
Gabe Sechan

私の意見では、あなたの#2のアプローチは、API /ライブラリに対してそれを行う正しい方法です。静的分析のアノテーションを使用して、コンパイル時にnullでメソッドを呼び出そうとするのを防ぎ、実行時にnullチェックを使用して、nullの場合に有用な例外を与えます(そして、コードで予期しないことが起こらないようにすばやく失敗します)オブジェクトは渡されます。nullチェックの前に// noinspection ConstantConditionsディレクティブを使用してIDEに警告を抑制させます(有効な理由でnullをチェックしているため)。

ランダムなNPEは、ライブラリ/ APIの作成者が何かを見逃していて、コードで処理されていないバグがあることを示しています。

IllegalArgumentException(または問題の説明を含むNPE-このインスタンスで使用する例外は意見ベースの引数)は、呼び出し元がメソッドの呼び出し方法に誤りを犯したことを示します。

ただし、最終的には、@ NonNullで注釈を付けた後にnullをテストするかどうかは、意見に基づいており、状況に依存します。

1
jt-gilkeson

コメントするには遅すぎるかもしれませんが、決して遅くなるよりはましです:)

Trautejavacプラグインがあり、null-メソッドパラメータの注釈に基づいて、生成されたバイトコードをチェックインします。

これが サンプルAndroidプロジェクト です。

0
denis.zhdanov