Javaは、C++のように演算子のオーバーロードを直接サポートしていません。この制限は、コードの可読性を向上させ、曖昧さを減らすために導入されました。C++の創造者であるビャーネ・ストロウストルップとJavaの創造者であるジェームズ・ゴスリングがこの問題について議論し、Javaでは開発者が自分のクラスに対して演算子の振る舞いを定義することを許可しないという決定がなされました。
演算子オーバーロードの問題は、ユーザー定義クラスに対して演算および論理を定義する過剰な自由が、追跡困難なバグやコードの可読性の低下を引き起こす可能性があることです。特に大規模なチームでは、その影響が顕著になります。
解決策として、ユーザーによる演算子のオーバーロードを禁止することです。ただし、Javaはそのクラス内でメソッドのオーバーロードをサポートし、演算子の振る舞いは明示的に定義されたメソッド(例:.add(), .equals(), .compareTo()など)を介して模倣できます。
コード例:
public class Vector2D { private final int x, y; public Vector2D(int x, int y) { this.x = x; this.y = y; } public Vector2D add(Vector2D other) { return new Vector2D(this.x + other.x, this.y + other.y); } } Vector2D v1 = new Vector2D(2, 3); Vector2D v2 = new Vector2D(1, 4); Vector2D sum = v1.add(v2); // 代わりに v1 + v2
主な特徴:
Javaで自分のクラスのために演算子「+」をオーバーロードしてオブジェクトを加算できますか?
答え: いいえ、Javaは作成されたクラスに対してユーザーによる算術演算子のオーバーロードをサポートしていません。例外は文字列に対してのみ適用されます:演算子「+」はStringBuilderを通じた連結を呼び出します。
equals()メソッドを定義すると、「==」演算子は値の比較として機能しますか?
答え: いいえ、「==」演算子はオブジェクトの参照を比較し、その内容を比較しません。値を適切に比較するには、オーバーライドされたequals()を使用します。
String a = new String("hello"); String b = new String("hello"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true
標準演算子が特定のクラスに対して異なる振る舞いをする例外はありますか?
答え: Javaでは、「特別」な振る舞いは演算子「+」を持つStringおよびプリミティブ型(自動プロモーションおよびアンボクシング)のみに実装されています。その他のクラスでは、演算子は標準的に動作します(つまり、オーバーロードされない)。
若い開発者がMoneyクラスを作成し、「==」を通じて2つのオブジェクトを比較して、値として比較できると考えました。その結果、プロダクションのみで表面化する等価性チェックのエラーが発生しました。
利点:
欠点:
プロジェクト内で自分のVectorクラスが作成され、すべての算術演算が明示的に実装され、「==」演算子はオブジェクトに対して使用されず、ドキュメントにはメソッドの動作のセマンティクスが記述されています。
利点:
欠点: