Java:オブジェクトがnullかどうかを確認する方法は?


87

Webから画像を取得するアプリケーションを作成しています。画像を取得できない場合は、別のローカル画像を使用する必要があります。

次の行を実行しようとしている間:

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable.equals(null)) {
  drawable = getRandomDrawable();
}

行if(drawable.equals(null))は、drawableがnullの場合に例外をスローします。

nullの場合に例外をスローせずにローカルイメージを取得するために、drawableの値をチェックする方法を知っている人はいますか(drawable = getRandomDrawable()を実行)。


23
if(drawable == null)を使用します。NULLオブジェクトでメソッドを呼び出すことはNullPointerExceptionです。
diciu 2010年

3
コメントの代わりにいつもの答えを書いてみませんか、diciu?
デーモン2010年

@JaredBurrows質問の目的を損なうような方法で質問のコードを編集しないでください!
Gilles'SO-悪であることをやめなさい '2014

@Gilles編集コメントを読んで、コードを読みやすくしました。
Jared Burrows 2014

@JaredBurrowsいいえ、編集は「フォーマット」の変更ではありませんでした。質問の対象であった非動作コードを、質問を無意味にする動作コードに変更しました。
Gilles'SO-悪であることをやめなさい '2014

回答:


35

編集されたJava8ソリューション:

final Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

drawable finalこの場合、宣言することができます。

Chasmoが指摘したように、Androidは現時点ではJava8をサポートしていません。したがって、このソリューションは他のコンテキストでのみ可能です。


7
おそらく良い考えではありません。条件の両側が評価されるFortran60に戻り、一方だけが使用されます。未使用のブランチに計算がある場合、これは悪いことです。これはほとんどの場合に当てはまるため、一般的には有用な方法ではありません。条件をCommonクラスに移動し、フォールバックURLを指定して、責任を一緒に維持できるようにします。
ピートカーカム2010年

1
この例はJava8で完全に書き直されたため、私のソリューションは無駄な評価に悩まされることはなくなりました(@PeteKirkhamが元のソリューションで指摘したように)。
デーモン2014

1
AndroidはJava8をサポートしていません。Java7までしかサポートしていません(キットカットがある場合)。それでも、invokedynamicはなく、新しい構文糖衣構文のみがサポートされています。それに加えて、Optional.ofは、値がnullではないため、orElseGetが不要であることを意味します。Optional.ofNullableこの場合に使用する必要があります。
マーティンシーラー2014年

179
Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable == null) {
    drawable = getRandomDrawable();
}

このequals()メソッドは、値が等しいかどうかをチェックします。つまり、2つのオブジェクトの内容を比較します。以来null目的ではないの内容にあなたのオブジェクトの内容を比較しようとすると、これがクラッシュしますnull

==以下のためのオペレータをチェックし、参照、それは2つのオブジェクトが実際にあるかどうかに見えることを意味平等、非常に同じオブジェクト。これには、オブジェクトが実際に存在する必要はありません。2つの存在しないオブジェクト(null参照)も同じです。


56
非常に価値のあるヒントを追加したいと思います。比較する文字列または定数がある場合は、常にそれらをequals句の最初に配置してください。(if( "coyote" .equals(myDogString)))は(if(myDogString.equals( "coyote")))よりもはるかに優れています。2番目のケースではmyDogStringがnullであり、最初のケースではNPEをスローするためです。 myDogStringがnullであるかどうかは関係ありません。
Thorsten S. 2010

20
ヨーダ記法として知られています:「コヨーテの場合、犬は...」
Thomas

1
また、Java 7にはObjects.equals()メソッドがあるので、ヨーダの構文を気にしないでください
maryokhin 2014年

21

私はこのアプローチを使用します:

if (null == drawable) {
  //do stuff
} else {
  //other things
}

このようにして、行の読みやすさが向上します。ソースファイルをすばやく読み取ると、nullチェックであることがわかります。

.equals()可能性のあるオブジェクトを呼び出すことができない理由に関してnull; あなたが持っているオブジェクト参照(つまり 'drawable')実際nullにある場合、それはヒープ上のオブジェクトを指していません。これは、への呼び出しequals()が成功する可能性のあるオブジェクトがヒープ上にないことを意味します。

頑張ってください!


4
偶発的な割り当てから身を守る方法として、if(<constant> == <variable>)構文も好みます。
スコット

8

DIY

private boolean isNull(Object obj) {
    return obj == null;
}

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (isNull(drawable)) {
    drawable = getRandomDrawable();
}

6
drawable.equals(null)

上記の行は、ドローアブルオブジェクトの「equals(...)」メソッドを呼び出しています。

したがって、drawableがnullでなく、それが実際のオブジェクトである場合、「equals(null)」メソッドを呼び出すとすべてうまくいき、「false」が返されます。

ただし、「drawable」がnullの場合は、nullオブジェクトで「equals(...)」メソッドを呼び出すことを意味します。存在しないオブジェクトでメソッドを呼び出すことを意味するため、「NullPointerException」がスローされます。

オブジェクトが存在し、それがnullでないかどうかを確認するには、次を使用します

if(drawable == null) {
    ...
    ...
}

上記の条件では、参照変数「drawable」がnullであるか、何らかの値(そのオブジェクトへの参照)が含まれていることを確認しているため、drawableがnullの場合でも例外はスローされません。

null == null

は有効です。



0

NullPointerExceptionをキャッチする方がおそらく少し効率的です。上記のメソッドは、ランタイムがnullポインターを2回チェックしていることを意味します。


1
ダブルチェックインif x == nullソリューションはどこにありますか?
デーモン2010年

ifステートメントの後、オブジェクトが使用されると、ランタイムはnullポインターを再度チェックします。しかし、これがコンパイラによって最適化されているかどうかはわかりません。
トムR

4
これは、制御フローとして例外を使用するという、従来の常識に反します。
James

1
例外は、スタックトレース全体を作成する必要があるため、非常にコストがかかります。
デーモン2014

0

google guava libsを使用してis-null-check(デーモンの更新)を処理します

Drawable drawable = Optional.of(Common.getDrawableFromUrl(this, product.getMapPath())).or(getRandomDrawable());

Optional今日はJava8を使用することをお勧めします。
デーモン2014

-1

オラクルJavaソース開発者にいくつかのアイデアを与えるためだけに:-)

このソリューションはすでに.Netに存在し、より読みやすくなっています。

Visual Basic.Netの場合

Drawable drawable 
    = If(Common.getDrawableFromUrl(this, product.getMapPath())
        ,getRandomDrawable()
        )

C#では

Drawable drawable 
    = Common.getDrawableFromUrl(this, product.getMapPath() 
        ?? getRandomDrawable();

これらのソリューションは、ラムダ式を使用せずに、新しい演算子を追加するだけで、オプションのJavaソリューション(デフォルトの文字列は元の値がnullの場合にのみ評価されます)として強力です。

Javaソリューションとの違いをすぐに確認するために、2つのJavaソリューションを追加しました

Javaでオプションを使用する

Drawable drawable = 
    Optional.ofNullable(Common.getDrawableFromUrl(this, product.getMapPath()))
        .orElseGet(() -> getRandomDrawable());

Javaで{}を使用する

Drawable drawable = Common.getDrawableFromUrl(this, product.getMapPath());
if (drawable != null)
    {
    drawable = getRandomDrawable();
    }

個人的に、私はVB.Netのような私が好む?? C#またはif {}Javaで解決...あなたは?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.