Javaでのオペレーターのオーバーロード


回答:


235

いいえ、Javaはユーザー定義の演算子オーバーロードをサポートしていません。「カスタム」演算子のオーバーロードに近いJavaの唯一の側面は、文字列の+の処理です。これにより、定数のコンパイル時の連結またはStringBuilder / StringBufferを使用した実行時の連結が行われます。ただし、同じように動作する独自の演算子を定義することはできません。

Javaのような(とJVMベースの)言語の場合はありませんサポート演算子のオーバーロードを、あなたが見て可能性がKotlinGroovyの。または、Javaコンパイラプラグインソリューションで運が見つかるかもしれません。


4
Javaでラッパーを作成できないとおっしゃっていますか?IntegerのようなSmallIntegerのような?
フセイントゥグルルブキシク2012

3
@tuğrulbüyükışık:既存のすべてのプリミティブ型のラッパーはすでにありますが、独自の新しいラッパー型を作成したい場合、言語で特定のサポートがあるため、他のラッパー型のように動作させることはできません。
Jon Skeet

1
おかげで、私はそれについてグーグルで検索できませんでした。2つのプリミティブ(doubleとint ---> good precision + good range)で構成される複雑な変数を作成できるかどうかを知りたい
フセイントゥグルルブキシク

40
@djaqeel:演算子のオーバーロードにより、使用方法を誤るとコードが読みにくくなります。うまく使用すると、読みやすさのIMOが大幅に向上します。BigIntegerJava で使用するコードを見て、次にBigIntegerC#で演算子を使用して同様のコードを見てください。デリゲートがOOPの原則をどのように破るかはわかりません。反対意見よりも正確である必要があります。Javaデザイナにさまざまな機能が含まれていなかった理由の詳細はわかりませんが、リソースのプレッシャーと、言語を小さくシンプルに保ちたいという欲求が混在しているのではないかと思います。
Jon Skeet、2013年

4
私はこれが遅いことを知っていますが、例は千の議論の価値があります。与えられたm0として、Matrixそしてv0v1v2v3、およびv4などVectorの、単にそれはあなたがするのにかかる時間の長さを比較正しく、次の数式を解釈しますm0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);。オペレーターのオーバーロードのサポートが含まれていた場合は、として記述されている可能性がありますm0.transpose() * (v0 + v1 * v2).cross(v3) - v4;
code_dredd 2017年

38

演算子のオーバーロードは、JavaでString型の連結に使用されます。

String concat = "one" + "two";

ただし、独自の演算子オーバーロードを定義することはできません


26

+文字列に対してオーバーロードされていることを指摘しているすべての人々に加えて-、浮動小数点演算と整数演算の両方に対してもオーバーロードされ*てい/ます。

[編集] %は浮動小数点に対してもオーバーロードされています。これは、CまたはC ++のバックグラウンドを持っている人にとっては少し驚きかもしれません。


21

Javaでは、演算子のオーバーロードは許可されていません。推奨されるアプローチは、クラスのメソッドを定義してアクションを実行することです:a.add(b)ではなくa + b。JavaがCのような言語から除外された他のビットの要約をここで見ることができます:CおよびC ++から削除された機能


2
重要なことは、Javaソースファイルをコンテキストに依存しないようにする設計目標です。非常に大きな(MLOC)を読み込もうとすると、マクロヘビーCプログラムの学習曲線は非常に長くなります。同等(またはそれ以上)のJavaプログラムは、小さなJavaプログラムよりも簡単に理解できます。。で仕事にブルーカラーのプログラマのための言語を[と定型の冗長性が有害であると考えて誰もが専門家の認知にチャンクについてお読みください。]:ゴスリングが言ったように
ティムWilliscroft

2
oracleのおかげで、java.sun.comリンクは機能しません。できれば、更新されたリンクをお知らせください。
Syed Aqeel Ashiq 2013年

17

Javaでは演算子のオーバーロードが許可されていないため、これを自分で行うことはできません。

1つのただし例外です。+および+ =は、Stringオブジェクトに対してオーバーロードされます。


8
Javaには、演算子のオーバーロードの他の多くの例があります。たとえば&|、および^のためにオーバーロードされているbooleanと整数型。実際、算術演算子と関係演算子は、さまざまな数値型に対して多重定義されています。(もちろん、オーバーロードのセマンティクスははるかに近い...)
スティーブンC

16

他の多くの人が答えたように:Javaはユーザー定義の演算子のオーバーロードをサポートしていません。

これはトピックから外れているかもしれませんが、いくつかの回答で読んだことについてコメントしたいと思います。

読みやすさについて。
比較:

  1. c = a + b
  2. c = a.add(b)

もう一度見てください!
どちらがより読みやすいですか?

ユーザー定義型の作成を可能にするプログラミング言語は、組み込み型(またはプリミティブ型)と同じように動作できるようにする必要があります。

したがって、Javaはジェネリックプログラミングの基本原則を破り
ます。組み込み型のオブジェクトをユーザー定義型のオブジェクトと交換できるはずです。
(不思議に思うかもしれません:「彼は '組み込みのオブジェクト'と言ったのですか?」はい、ここを参照してください。)

文字列連結について:

数学者は、集合の可換演算に記号+を使用します。
したがって、a + b = b + aであることが確認できます。
(ほとんどのプログラミング言語での)文字列連結は、この一般的な数学的表記を尊重しません。

a := "hello";
b := "world";
c := (a + b = b + a);

またはJavaで:

String a = "hello";
String b = "world";
boolean c = (a + b).equals(b + a);

補足:
Javaの平等とアイデンティティがどのように混同されているかに注意してください。==(等号)記号は以下を意味
します。プリミティブ型の等価性。
b。ユーザー定義タイプの同一性検査、したがって、等価のために関数 equals()を使用することが強制されます。
しかし...これは演算子のオーバーロードとどう関係しているのでしょうか?
言語が演算子のオーバーロードを許可している場合、ユーザーは等値演算子に適切な意味を与えることができます。


シンボル==は、CおよびC ++の場合と同様に、Javaでも同等に使用されます。これは、オペレーターのオーバーロードとは関係ありません。
ホットリックス2014年

2
Javaのoperator ==は、プリミティブ型の等価性のみを意味します。ユーザー定義型の場合、IDを意味します。C ++ではセマンティクスはユーザーが定義しますが、組み込みのセマンティクスである同等性を保持する必要があります。文字列a = "hello"; 文字列b = "hello"; ブールc =(a == b);
Fernando Pelliccioni 2014年

3
最初のコメントで言ったことは間違っています。正しい?Cでユーザー定義型の同等性と同一性をテストする方法を教えてください。そうです、同等性に関する私のコメントはOTですが、それを明確にしました(「補足」を参照)。私がプログラミング言語を作成していないからといって、既存の言語を批判できないわけではありません。批判を宗教戦争だと思っていたらごめんなさい。
Fernando Pelliccioni 2014年

1
長いことを短く言えば、Javaは最悪です。
Kolya


6

XtendをJavaコードとともに使用するだけです。オペレーターのオーバーロードをサポートします。

    package com.example;

@SuppressWarnings("all")
public class Test {
  protected int wrapped;

  public Test(final int value) {
    this.wrapped = value;
  }

  public int operator_plus(final Test e2) {
    return (this.wrapped + e2.wrapped);
  }
}

package com.example

class Test2 {

    new() {
        val t1 = new Test(3)
        val t2 = new Test(5)
        val t3 = t1 + t2
    }

}

公式ウェブサイトには、各オペレーターに実装するメソッドのリストがあります!


5

または、Java Groovyを作成してこれらの関数をオーバーロードするだけで、目的を達成できます

//plus() => for the + operator
//multiply() => for the * operator
//leftShift() = for the << operator
// ... and so on ...

class Fish {
    def leftShift(Fish fish) {
        print "You just << (left shifted) some fish "
    }
}


def fish = new Fish()
def fish2 = new Fish()

fish << fish2

誰がグルーヴィーになりたくない、または使いたくないのですか?:D

いいえ、JavaでコンパイルされたGroovy JARを同じ方法で使用することはできません。それでもJavaのコンパイラエラーです。


1

C ++とは異なり、Javaはユーザー定義の演算子のオーバーロードをサポートしていません。オーバーロードはJavaの内部で行われます。

+(プラス)を例にとります。

int a = 2 + 4;
string = "hello" + "world";

ここで、plusは2つの整数を追加し、2つの文字列を連結します。したがって、Javaは内部演算子のオーバーロードをサポートしていますが、ユーザー定義はサポートしていないと言えます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.