1. ホーム
  2. java

[解決済み] なぜJavaには演算子のオーバーローディングがないのですか?

2022-03-21 03:09:55

質問

C++からJavaに移ってきて、明らかに答えのない疑問は、なぜJavaには演算子のオーバーローディングがなかったのか、ということです。

はないでしょうか。 Complex a, b, c; a = b + c; よりもはるかにシンプルです。 Complex a, b, c; a = b.add(c); ?

の有効な引数、既知の理由はあるのでしょうか? ではなく 演算子のオーバーロードを許可していますか?その理由は恣意的なものなのか、それとも時間の経過とともに失われたものなのでしょうか?

解決方法は?

で参照されているオブジェクトの以前の値を上書きしたいと仮定します。 a その場合、メンバ関数を呼び出す必要があります。

Complex a, b, c;
// ...
a = b.add(c);

C++では、この式はコンパイラに、スタック上に3つのオブジェクトを作成し、加算を実行し コピー その結果、一時的なオブジェクトから既存のオブジェクトに値が移動します。 a .

しかし、Javaでは operator= は参照型に対して値のコピーを実行しません。また、ユーザーが作成できるのは新しい参照型だけで、値型は作成できません。そのため、ユーザー定義型の Complex というのは、代入とは、既存の値への参照をコピーすることだからです。

代わりに考えてみましょう。

b.set(1, 0); // initialize to real number '1'
a = b; 
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail

C++では、これは値をコピーするので、比較の結果はnot-equalとなる。Javaでは operator= は参照コピーを行うので ab は同じ値を参照するようになりました。その結果、オブジェクトはそれ自身と等しく比較されるため、比較は「等しい」を生成します。

コピーと参照の違いは、演算子のオーバーロードの混乱に拍車をかけるだけです。セバスチャンが言ったように、JavaとC#は値の等価性と参照の等価性を別々に扱わなければならない --。 operator+ は値やオブジェクトを扱うと思われますが operator= は、参照を扱うためにすでに実装されています。

C++では、一度に一種類の比較しか扱わない方が混乱が少なくて済みます。例えば Complex , operator=operator== はどちらも値に関する作業で、それぞれ値のコピーと値の比較を行っています。