- 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を書く人は、なんででしょうね?
代入の時の書き方を意識しているのでしょうか。
|