public void increment(){
int zero = 0;
int oneA = zero++; // Compiles
int oneB = 0++; // Doesn't compile
int oneC = getInt()++; // Doesn't compile
}
private int getInt(){
return 0;
}
それらはすべてintですが、なぜB&Cはコンパイルされないのですか? ++
演算子が= 0 + 1;
と異なる方法と関係がありますか?
操作の引数が無効です++ /-
_i++
_は、変数i
への割り当てです。
あなたの場合、_zero++
_は_zero = zero + 1
_と同等です。したがって、_0++
_は_0 = 0 + 1
_を意味しますが、これは意味がなく、getInt() = getInt() + 1
も意味します。
より正確に :
_int oneA = zero++;
_
手段
_int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1
_
_int oneB = 0++;
_
手段
_int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.
_
_int oneC = getInt()++;
_
手段
_int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.
_
より一般的な観点から、変数はL値です。これは、メモリの場所を参照しているため、割り当てることができることを意味します。 [〜#〜] l [〜#〜] in [〜#〜] l [〜#〜]-値は左側を表しますL値が代入演算子の左側または右側にある場合でも(たとえば、_=
_)、代入演算子の(つまり、_x = y
_)。
反対はR値([〜#〜] r [〜#〜]は右代入演算子の側を表します)。 R値は、L値に何かを割り当てるために、割り当てステートメントの右側でのみ使用できます。通常、R値はリテラル(数値、文字列など)とメソッドです。
[〜#〜] jls [〜#〜] で述べたように:
後置式の結果は、数値型(§5.1.8)に変換可能な型の変数である必要があります。そうでない場合、コンパイル時エラーが発生します。
getInt()
はint
ではありません
getInt()
はint
を返します
_++
_演算子は2つのことを行いますincrement
+ assignment
したがって、_++
_演算子が機能するには、インクリメント操作の結果を格納する変数が必要ですが、_0
_とgetInt()
はどちらもそうではありません。
事前演算子と事後演算子は、呼び出された変数または左辺値のみを操作します。左辺値は左の値の略です。つまり、割り当ての左に立つことができるものです。あなたの例では:
zero = 1; // OK
0 = 1; // Meaningless
getInt() = 1; // Also meaningless
// jk
BとCはどちらも、コンパイラに次のように言わせます。
予期しないタイプ、必須:変数、検出:値
したがって、値をインクリメントすることはできず、変数のみをインクリメントできます。
ポストインクリメント演算子がintを返すメソッドで機能しないのはなぜですか?
これはゲッターメソッドであり、ゲッターを介して値を変更することは意味がないためです。
int z = x + y++;
と同等です:
int z = x + y;
y = y + 1;
したがって、次のようなものを持つことは無効です。
int z = x + getY()++;
これは次と同等です:
int z = x + getY();
getY() = getY() + 1; // invalid!
0 ++
これは0 = 0 + 1;
と同等であり、確かに不可能です。
つまり、割り当てるにはl-value
である必要があります。
getInt()++;
ここで同様の理由。
なぜなら0
はrValue
です(つまり、代入演算子の右側からのみ使用できます)not a lValue
。
++
演算子は値をインクリメントし、それ自体に設定するため、0++
エラーが発生します。
私の答えは、そのような「箱から出して」です。
演算子の使用法に疑問がある場合、この演算子の「オーバーロードされた関数はどれに相当するか」と思いますか?
Java演算子には演算子のオーバーロードがなく、解決策を作成するための代替方法にすぎないことを私は知っています。
この場合:
...
x++;
...
次のように読む必要があります:
...
int /* function */ postincrement (/* ref */ int avalue)
{
int Result = avalue;
// reference value,
avalue = avalue + 1;
return Result;
}
...
postincrement(/* ref */ x);
...
そして:
...
++x;
...
...
int /* function */ preincrement (/* ref */ int avalue)
{
// reference value,
avalue = avalue + 1;
int Result = avalue;
return Result;
}
...
preincrement(/* ref */ x);
...
したがって、両方のバージョンの「++」は、参照によって変数パラメーターを受け取る関数として機能します。
したがって、「0 ++」のようなリテラル値または「getInt()++」のような関数結果は、変数参照ではありません。
乾杯。
関数の戻りはRHS式であるため、前後のインクリメント/デクリメント操作はLHS式にのみ適用できます。
postincrementとpreincrementは、変数を使用した場合にのみ適用できます。したがって、最初のケースはコンパイルされます。