a += 10
とはどちらも同じですかa = a + 10
、それとも違いがありますか? Javaで課題を勉強しているときに、この質問を受けました。
5 に答える
キャスティングについて言及したように...この場合には違いがあります:
byte a = 5;
a += 10; // Valid
a = a + 10; // Invalid, as the expression "a + 10" is of type int
Java 言語仕様セクション 15.26.2 から:
の形式の複合代入式は、
E1 op= E2
はE1 = (T)((E1) op (E2))
のT
型ですがE1
、E1
は 1 回だけ評価されます。
興味深いことに、彼らが仕様で示した例:
short x = 3;
x += 4.6;
Java では有効ですが、C# では有効ではありません... 基本的に C# では、コンパイラは += と -= の特別なケースを実行して、式が対象の型であるか、対象の型の範囲内のリテラルであることを確認します。
違いはありません。一方は他方の省略形です。コンパイラでさえ、両方に対して同じ命令を生成します。
編集:私が見つけたように、コンパイラは両方に対して同じコードを生成しません。これをチェックしてください:
dan$ cat Test.java
public class Test {
public static void main(String[] args) {
int a = 0;
a = a + 10;
a += 20;
}
}
dan$ javap -c Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: iadd
6: istore_1
7: iinc 1, 20
10: return
}
したがって、特に Java の初心者、または最小レベルでの最適化を心配していない人にとって、短い答えは、それらは交換可能であるということです。長い答えは、iadd と iinc について読んでいるかどうかによって異なります。
編集2:わかりました、戻ってきました。命令仕様は(おおよそ)次のとおりです。
iadd - スタックの上位 2 つの int を追加します
iinc - ローカル変数を定数でインクリメントします
上で見たように、右側に定数がある限り、iinc を使用していくつかの命令を保存できます。
しかし、私たちが持っているとどうなりますか
a += a
?
次に、コードは次のようになります。
7: iload_1
8: iload_1
9: iadd
10: istore_1
これは、 がある場合に得られるものと同じですa = a + a
。
これは、Java 言語仕様のセクション 15.25.2で定義されています。顕著な部分は次のとおりです。
E1 op= E2 の形式の複合代入式は、E1 = (T)((E1) op (E2)) と同等です。ここで、T は E1 の型ですが、E1 は 1 回だけ評価されます。
つまり、あなたの場合、違いは暗黙の型キャストです。
byte a = 100;
a += 1000; // compiles
a = a + 1000; // doesn't compile, because an int cannot be assigned to a byte.
あなたが示す式では、次のような式で同等です。
array[getIndex(context)][some / complex + expression] += offset;
+= 演算子 (およびその他の代入演算子) が役立つ状況がわかります。式が自明でない場合、+= 演算子は間違いを防ぎ、可読性を向上させ、保守性を向上させます。