- PR -

if条件式の右辺と左辺

投稿者投稿内容
Orphan
ベテラン
会議室デビュー日: 2004/02/06
投稿数: 54
投稿日時: 2007-11-20 00:20
String s = null;
//ここでsに何かしら値を代入(nullかも)

//【1】右辺がnull
if(s==null){
 処理1;
}
//【2】左辺がnull
if(null==s){
 処理1;
}

if文の条件式で【1】と【2】は両方コンパイルが通りますが
【1】と【2】ではなにか差があるのでしょうか?
それとも全く同じ意味でしょうか?

[ メッセージ編集済み 編集者: Orphan 編集日時 2007-11-20 00:22 ]
温州蜜柑
ベテラン
会議室デビュー日: 2005/01/24
投稿数: 65
お住まい・勤務地: 東京都
投稿日時: 2007-11-20 00:27
javap で見てみると、なにやら動きが異なるようです。

コード:
hoge> cat X.java
class X {
        public static void main(String [] args){
                String s = null;
                if ( s == null ) {
                }
        }
}
hoge> cat Y.java
class Y {
        public static void main(String [] args){
                String s = null;
                if ( null == s ) {
                }
        }
}
hoge> javap -private -c X
Compiled from "X.java"
class X extends java.lang.Object{
X();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>")V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   astore_1
   2:   aload_1
   3:   ifnonnull       6
   6:   return

}

hoge> javap -private -c Y
Compiled from "Y.java"
class Y extends java.lang.Object{
Y();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>")V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   astore_1
   2:   aconst_null
   3:   aload_1
   4:   if_acmpne       7
   7:   return

}


かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-11-20 00:32
javaのif文はbooleanしか評価できないので、あまりバグになりにくいですが、
CやJavaScriptやPHPなど、(s == null)のつもりが(s = null)でも動くので、
そのバグを防ぐためのテクニックです。

s == nullはsがnullであるかの評価結果になりますが、
s = nullはsにnullを代入した結果が評価結果となります。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2007-11-20 00:40
同じ意味です。
【2】はC言語を使う人がコーディングミスを防ぐための用いる
一つの記述スタイルですね。Javaでは特に意味はありません。

温州蜜柑さんのご指摘からするとバイトコードは異なる場合があるようです。
動作結果には影響ありません。

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-11-20 01:22
バイトコードに変化があるってのはおもしろいなぁ。
今度調べてみよう。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-11-20 10:22
引用:

Orphanさんの書き込み (2007-11-20 00:20) より:
if文の条件式で【1】と【2】は両方コンパイルが通りますが
【1】と【2】ではなにか差があるのでしょうか?
それとも全く同じ意味でしょうか?


うろ覚えですが、評価の順序は、かならず、左辺→右辺、のはずです。
ですから、なんらかの差はあるし、まったく同じ意味ではないでしょう。
しかし、このコードを書いた人が、この差を利用しているとも思えませんので、そういう意味で言えば、差はないし、まったく同じ意味でしょう。

実装依存とは違い、言語仕様で順序が決まっているけど、その順序を利用していない、そういうのってなんと呼べば良いんでしょう?

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
a-san
ベテラン
会議室デビュー日: 2004/06/01
投稿数: 53
投稿日時: 2007-11-20 22:01
Javaコードに差があるのは興味深いですね。
まず、コンストラクタはどちらも同じなので省きます。
クラスXのmain()から行きましょう♪
コード:
  Code:
   // String s = null;
   0:   aconst_null      // スタックに定数のオブジェクトnullを積む
   1:   astore_1         // ローカル変数1(つまりs)にスタックのオブジェクトを格納する。
   // if ( s == null ) {
   2:   aload_1          // ローカル変数1のオブジェクトをスタックに積む。
   3:   ifnonnull   6    // もし、スタックの先頭がnullでなければ6へジャンプ
   // }
   6:   return           // メソッドを終了


次にクラスYのmain()です。最初の2行はXと同じです。
コード:
  Code:
   // String s = null;
   0:   aconst_null      // スタックに定数のオブジェクトnullを積む
   1:   astore_1         // ローカル変数1(つまりs)にスタックのオブジェクトを格納する。
   // if ( null == s ) {
   2:   aconst_null      // スタックに定数のオブジェクトnullを積む
   3:   aload_1          // スタックにローカル変数1(つまりs)を積む。
   4:   if_acmpne   7    // もし、スタックの2つのオブジェクトが等しくないなら7へジャンプ
   // }
   7:   return           // メソッドを終了


Xの方は ifnonnull が使えるので、スタックに積まなくても判断できます。
その分、1バイト少なくてすみます。
で、Xの方が短いから効率がいいか?というと
どちも微々たるものなのでほとんど変わらないし、最適化でどう動くか分かりません。
また、1バイト減って効率がいいか?と言われてもギモンですね。
どちらにしても、気にする必要はないでしょう。
Ray
ベテラン
会議室デビュー日: 2007/09/13
投稿数: 88
投稿日時: 2007-11-21 02:39
私はnull==sと書く人です。
理由はすでに出ているように別の言語でのバグを減らすため。
習慣にしないと意味がないのでJavaでも同じように書いています。

確かエキスパートCプログラミングを読んだ時に、気圧計でビルの高さを測る方法の他に覚えたことです。

ちなみに…
ifでなくても比較演算するときはそう書きます。
nullでなくてもどちらかが定数だったら左辺に書きます。

逆に…
右辺にnullを書く人は、なんででしょうね?
代入の時の書き方を意識しているのでしょうか。

スキルアップ/キャリアアップ(JOB@IT)