object == nullまたはnull == object?


96

チェックnull == objectよりいい人から聞いたobject == null

例:

void m1(Object obj ) {
   if(null == obj)  // Is this better than object == null ? Why ?
       return ;
   // Else blah blah
}

何か理由があるのですか、それとも別の神話ですか?手伝ってくれてありがとう。


271561と1957836のだまし絵(これが「Javaで」と言う場合を除く)
紀州

20
JavaはC#と異なっている
Jijoy

5
パフォーマンス大幅に向上した場合、コンパイラーはそれを最適化します...
Andreas Dolk

null言及、アクションのデフォルトのコースは、NPEをスローするようにする必要があります。一部の優れたライブラリ(JDK7 Javaライブラリなど)には、次のようなメソッドがありpublic static <T> T notNull(T obj) { if (obj == null) { throw new NullPointerException(); } else { return obj; } }ます。@NonNull(または@Nonnull?)もありますが、「消去」されます。
トム・ホーティン-10

回答:


140

これはおそらく、この種のタイプミス(=ダブルではなくシングル)を回避するために、Cから学んだ習慣==です。

if (object = null) {

定数をの左側に置くという慣例は==、Javaでは実際には有用ではありません。Javaでは式が値にif評価される必要があるbooleanため、定数がでない限り、booleanいずれかの方法でコンパイルエラーが発生します。引数。(それがブール値である場合は、==とにかく使用しないでください...)


4
タイプミスは、Javaのコンパイルエラーになりので、これは、Javaのために非常に有益な習慣をイマイチ
radai


3
ブール値の場合は@Chandru、x.booleanValue()またはを使用できます!x.booleanValue()x == trueまたはx == false条件式で悪臭、私見です。
Laurence Gonsalves

2
ここでヌルをチェックしています。また、nullはtrueでもfalseでもないため、ブール値のnullをチェックする必要がある場合もあります。
Chandra Sekar

1
null == objectタイプミスで誤ってオブジェクトを上書きしないようにするためだけに慣れるのは、ユースケースであってはなりません。つまり、私たちは自分が「null」を最初に使用するようになったため、自分でトレーニングを行っています。これは、コードが期待どおりに機能することを意味するものではありません。null = objectの場所に指定してもnull == object、プログラムは期待どおりに動作しません。この場合、この規則に従う意味はありません。
VanagaS 2017年

32

他の人が言ったように、タイプミスを回避するのはCから習得した習慣です-Cでさえ、警告を出すのに十分高い警告レベルのまともなコンパイラーを期待します。Chandruが言うように、この方法でJavaのnullと比較しても、型の変数Boolean(サンプルコードにはない)を使用している場合にのみ問題が発生します。これはかなりまれな状況であり、他の場所でコードの記述方法を変更する価値がある状況ではありません。(この場合でも、オペランドを逆にする必要はありません。それらを逆にすることを検討するのに十分明確に考えている場合は、等号を数えることができると確信しています。)

何をしていません言及されては、多くの人が(私自身は確かに含まれている)を見つけることですif (variable == constant)、それはあなた自身を表現するより自然な方法です-フォームを読みやすくします。これは、慣習をCから盲目的にコピーしない理由です。ある環境で有用である可能性があるものが別の環境でも有用であると想定する前に、常に(ここで行っているように)プラクティスに疑問を投げかける必要があります。


3
あなたが言ったすべての言葉、特に「慣習を盲目的にコピーする」部分に同意します。私は今コードを読んでいて、null =オブジェクトスタイルは私を困らせて、調べてここに来ました。コーダーは何を考えていましたか?
Adrian M

28

オブジェクトのタイプがである場合を除いて、これはJava(1.5以降)ではあまり価値がありませんBoolean。その場合でも、これは便利です。

if (object = null)オブジェクトが実行時にat Booleanをスローする場合、Java 1.5以降ではコンパイルエラーは発生しませんNullPointerException


あなたはおそらくそれがコンパイルの失敗を引き起こすことを意味しました:)
vava

7
いいえ、オブジェクトがブール値の場合、コンパイルエラーは発生しません。
Chandra Sekar

ブール値以外のすべてのオブジェクトタイプで同じではありませんか?
Ciro Santilli郝海东冠状病六四事件法轮功

2
非ブール型の場合、式「object = null」の型がブール型にならないため、コードはコンパイルされません。自動ボックス化により、ブール値用にコンパイルされます。
Chandra Sekar

しかし、なぜこの動作がブール値なのか?根拠はありますか?
Rohit Banga

9

Javaでは正当な理由はありません。

他のいくつかの答えは、偶然に等価ではなく誤って割り当てを行うことができるためであると主張しています。しかし、Javaでは、ifにブール値を指定する必要があるため、次のようにします。

if (o = null)

コンパイルされません。

Javaでこれが問題になるのは、変数がブール値の場合だけです。

int m1(boolean x)
{
    if (x = true)  // oops, assignment instead of equality

4
しかし、なぜあなたはこれまでに、== trueまたは同じように書くでしょうか== true == true
トム・ホーティン-10

7
書く理由はありません== true。しかし、私はキャリアの中で非常に多くの悪いコードを見てきました。なぜ誰かが何かを書くのかと尋ねるのではなく、一部の人々が不必要な/疑わしいコードを書いたことを受け入れるだけです。
R Samuel Klatchko、

1
確かに、多くの貧弱なコードが飛び交ってx == trueいますが、誤ってと記述されている可能性があるため悪いと考えると、単にの代わりx = trueに変更するのはあまり意味がありません。true == xx
Holger

9

これは、以下にも密接に関連しています。

if ("foo".equals(bar)) {

これは、NPEを処理したくない場合に便利です。

if (bar!=null && bar.equals("foo")) {

便利かもしれませんが危険かもしれませんblue-walrus.com/2010/11/…–
オリバーワトキンス

@OliverWatkins:この記事は弱いと思います。変数の型がintであると想定します。初期化しないでおくと、値は0になり、記事の約束は成立しません。Stringsがオブジェクトであり、intがプリミティブであるという事実は、プログラマーが変数の初期化を忘れることがあるという事実とは無関係です。この質問では、null文字列比較の問題を単純に解決します。
cherouvim 14年

事実@cherouvim intプリミティブ型であるであることが呼び出すことが不可能であるように、関連equalsint使用する天気を議論するにはポイントが存在しない、従って、x.equals(constant)又はconstant.equals(x)ためのint値。そしてのためIntegerの値、デフォルト値があるnullのではなく0
Holger

5

このトリックは、v = null一種のタイプミスを防ぐためのものです。

ただし、Javaはブール式のみをif()条件として許可するため、トリックがあまり意味をなさないため、コンパイラはこれらのタイプミスをとにかく見つけます。

ただし、C / C ++コードの場合でも、これは貴重なトリックです。


3

同じ理由で、Cでそれを行います。代入は式なので、誤っての=代わりに使用しても上書きできないように、リテラルを左側に配置します==


しかし、ブール型についてはJavaの問題だけですよね?他のタイプの割り当てはブール型を持たないため、コンパイラエラーが発生します。
スコットスミス

1
いいえ、Javaコンパイラはそのようなタイプミスを好きな順序でキャッチします
vava

@Jijoy-これはパフォーマンスとは関係ないと思います。これは、恐ろしい条件式内の代入式の間違いを回避するためのCの古いトリックのように聞こえます。x等しいかどうかを確認しようとしている場合5、誤ってを入力if (x = 5)すると、静かにコンパイルされます(そしてtrueの値に関係なく、常にに評価されますx)。ただし、常に最初にリテラルを指定する習慣になっている場合: 'if(5 = x)'、コンパイラーは作業を再確認して、デバッガーでのヘッドバンギング時間を節約できます。最新のコンパイラーは、この習慣を不要にします。
スコットスミス

6
-1:誤って=を使用すると、Javaでコンパイルされません。したがって、Cの理由は当てはまりません。
Jon Skeet、

技術的にobjは、タイプjava.lang.Boolean(big B)の場合、違いが生じる可能性があります(実際に試したわけではなく、何でもかまいません)。
トムホーティン-タックライン

3

これは、定数を左側に置くことを好む人向けです。ほとんどの場合、定数が左側にあると、NullPointerExceptionがスローされなくなります(または別のnullcheckが発生します)。たとえば、Stringメソッドのequalsはnullチェックも行います。左側に定数があると、追加のチェックを書くことができなくなります。これは別の方法で後で実行されます。左側にnull値があることは、一貫しているだけです。

お気に入り:

 String b = null;
 "constant".equals(b);  // result to false
 b.equals("constant");  // NullPointerException
 b != null && b.equals("constant");  // result to false

このNPEの非表示は、さらに下流のバグを見つけるのをさらに難しくします
Oliver Watkins

2

ヨーダ様書き方コンディション

Javaで

String myString = null;
if (myString.equals("foobar")) { /* ... */ } //Will give u null pointer

ヨーダ状態

String myString = null;
if ("foobar".equals(myString)) { /* ... */ } // will be false 

1

次のコードと比較してください:

    String pingResult = "asd";
    long s = System.nanoTime ( );
    if ( null != pingResult )
    {
        System.out.println ( "null != pingResult" );
    }
    long e = System.nanoTime ( );
    System.out.println ( e - s );

    long s1 = System.nanoTime ( );
    if ( pingResult != null )
    {
        System.out.println ( "pingResult != null" );
    }
    long e1 = System.nanoTime ( );
    System.out.println ( e1 - s1 );

出力(複数の実行後):

null != pingResult
325737
pingResult != null
47027

したがって、pingResult != null勝者です。


7
追加のループでテストを実行してください!または、IFステートメントを切り替えます。要するに、違いはありません!最初のループは常に低速です。
Marcel Jaeschke 2012

このテストでは、pingResultは常にnull以外です。pingResultがnullのタイミングはどうなりますか?私はそれがプラットフォームに依存しないことに賭けていますが、私のOracle Java 1.6 / Linuxスタックでは、結果は(ループ内で)ほぼ均一です。ただし、pingResultがnullの場合、両方のチェックが数パーセント速くなります。
Ogre Psalm33 2013

1
「pingResult!= nullブロックをnull!= pingResultブロックの前に置くと、「pingResult!= null 325737」のような結果になります
Sola Yang

@Sola Yangが言うように、前にpingResult!= nullを置くと、null!= pingResultよりも時間がかかることがわかります。pingResult!= nullがnull!= pingResultよりも速い場合、IDE(IntelliG、Eclipseなど)は、開発者にこのロールを使用するよう強制する警告を表示します;)
adil.hilmi

1

可換性があるため、object == nullnull == objectヨーダバージョン)の唯一の違いは、認知的な性質、つまり、コードがリーダーによって読み取られ、ダイジェストされる方法です。決定的な答えはわかりませんが、私が個人的には、検査しているオブジェクトと検査しているオブジェクトを比較するよりも、検査しているオブジェクトを他のものと比較する方が個人的に好む場合があります。まず件名、次に比較する値。

他の一部の言語では、この比較スタイルの方が便利です。

ただし、一般的に "="記号がないことを防ぐために、書くnull == objectことは守備的なプログラミングの誤解された行為だと思います。この特定のコードを回避するより良い方法は、junitテストで動作を保証することです。「=」の欠落の可能性のある間違いは、メソッドの入力引数に依存していないことを覚えておいてください。他の人によるこのAPIの正しい使用に依存していないため、代わりにjunitテストが完全に安全に保護されます。とにかく、動作を確認するためのjunitテストを作成する必要があります。欠落している「=」は当然範囲内です。

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