Überladung von Operatoren in Java

Antworten:

234

Nein, Java unterstützt keine benutzerdefinierte Operatorüberladung. Der einzige Aspekt von Java, der der "benutzerdefinierten" Operatorüberladung nahe kommt, ist die Behandlung von + für Zeichenfolgen, die entweder zur Verkettung von Konstanten zur Kompilierungszeit oder zur Verkettung zur Ausführungszeit mit StringBuilder / StringBuffer führt. Sie können jedoch keine eigenen Operatoren definieren, die auf die gleiche Weise handeln.

Für eine Java-ähnliche (und JVM-basierte) Sprache, die das Überladen von Operatoren unterstützt, können Sie sich Kotlin oder Groovy ansehen . Alternativ könnten Sie Glück mit einer Java-Compiler-Plugin-Lösung finden .

Jon Skeet
quelle
4
Sie sagen, wir können keinen Wrapper in Java erstellen? Wie SmallInteger wie Integer?
Huseyin Tugrul Buyukisik
3
@ tuğrulbüyükışık: Es gibt bereits Wrapper für alle vorhandenen primitiven Typen - aber wenn Sie Ihren eigenen neuen Wrapper-Typ erstellen möchten, können Sie ihn nicht wie die anderen verhalten, da sie in der Sprache spezifische Unterstützung haben.
Jon Skeet
1
danke, ich habe darüber gegoogelt und konnte nicht finden. Ich wollte wissen, ob ich eine komplexe Variable machen kann, die aus zwei
Grundelementen besteht
40
@djaqeel: Durch das Überladen von Operatoren wird der Code bei schlechter Verwendung weniger lesbar . Bei guter Verwendung kann die Lesbarkeit IMO erheblich verbessert werden. Schauen Sie sich Code an, der BigIntegerin Java verwendet wird, und schauen Sie sich dann ähnlichen Code an, der BigIntegerin C # mit Operatoren verwendet wird. Ich sehe nicht, wie Delegierte gegen OOP-Prinzipien verstoßen - Sie müssen in Ihren Einwänden viel präziser sein. Ich weiß nicht genau, warum die Java-Designer nicht verschiedene Funktionen integriert haben, aber ich vermute, dass es eine Mischung aus Ressourcendruck und dem Wunsch gibt, die Sprache klein und relativ einfach zu halten.
Jon Skeet
4
Ich weiß, dass dies spät ist, aber ein Beispiel ist tausend Argumente wert. Gegeben m0als ein Matrixund v0, v1, v2, v3, und v4wie Vectors, einfach vergleichen , wie lange es dauert , um richtig den folgenden mathematischen Ausdruck zu interpretieren m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);. Wäre die Unterstützung für das Überladen von Bedienern enthalten gewesen, hätte dies als geschrieben werden können m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;.
code_dredd
38

Das Überladen von Operatoren wird in Java für die Verkettung des String-Typs verwendet:

String concat = "one" + "two";

Sie können jedoch keine eigenen Operatorüberladungen definieren.

Teabot
quelle
26

Zusätzlich zu allen Personen, die darauf hinweisen, dass +für Strings überladen ist, -ist auch für Gleitkomma- und Ganzzahloperationen überladen, wie *und/ .

[edit] %ist auch für Gleitkommawerte überladen, was für Benutzer mit C- oder C ++ - Hintergrund eine kleine Überraschung sein kann.

MSalters
quelle
20

Java erlaubt keine Überladung von Operatoren. Der bevorzugte Ansatz besteht darin, eine Methode für Ihre Klasse zu definieren, um die Aktion auszuführen: a.add(b)statt a + b. Eine Zusammenfassung der anderen Java-Bits, die in C-ähnlichen Sprachen ausgelassen wurden, finden Sie hier: Aus C und C ++ entfernte Funktionen

rauben
quelle
2
Das Wichtigste ist das Entwurfsziel, Java-Quelldateien kontextunabhängig zu machen. Der Versuch, sehr große (MLOC), makrointensive C-Programme zu lesen, hat eine sehr lange Lernkurve. Ein vergleichbares (oder größeres) Java-Programm ist nicht schwerer zu verstehen als ein kleines Java-Programm. Wie Gosling sagte: Eine Sprache für blue collar Programmierer Arbeit in [Und wer glaubt , vorformulierten Ausführlichkeit ist schädlich sollte etwa Chunking in Experten - Erkenntnis lesen.].
Tim Williscroft
2
Dank oracle funktioniert keiner der Links auf java.sun.com. Können Sie bitte den aktualisierten Link angeben, wenn möglich?
Syed Aqeel Ashiq
17

Sie können dies nicht selbst tun, da Java keine Überladung von Operatoren zulässt.

Mit einer Ausnahme jedoch. + und + = sind für String-Objekte überladen.

Brian Agnew
quelle
8
Es gibt viele andere Beispiele für das Überladen von Operatoren in Java. Zum Beispiel &, |und ^sind für Überlastung booleanund Integral - Typen. Tatsächlich sind die arithmetischen und relationalen Operatoren für verschiedene numerische Typen überladen. (Natürlich ist die Semantik der Überladungen viel näher ...)
Stephen C
16

Wie viele andere geantwortet haben: Java unterstützt keine benutzerdefinierte Operatorüberladung.

Vielleicht ist dies kein Thema, aber ich möchte einige Dinge kommentieren, die ich in einigen Antworten gelesen habe.

Über Lesbarkeit.
Vergleichen Sie:

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

Schau nochmal!
Welches ist besser lesbar?

Eine Programmiersprache, mit der benutzerdefinierte Typen erstellt werden können, sollte es ihnen ermöglichen, auf die gleiche Weise wie die integrierten Typen (oder primitiven Typen) zu handeln.

Java bricht also ein Grundprinzip der generischen Programmierung:
Wir sollten in der Lage sein, Objekte von eingebauten Typen mit Objekten von benutzerdefinierten Typen auszutauschen.
(Sie fragen sich vielleicht: "Hat er 'eingebaute Objekte' gesagt?". Ja, siehe hier .)

Informationen zur Verkettung von Zeichenfolgen:

Mathematiker verwenden das Symbol + für kommutative Operationen an Mengen.
Wir können also sicher sein, dass a + b = b + a.
Die Verkettung von Zeichenfolgen (in den meisten Programmiersprachen) berücksichtigt diese allgemeine mathematische Notation nicht.

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

oder in Java:

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

Extra:
Beachten Sie, wie in Java Gleichheit und Identität verwechselt werden. Das Symbol == (Gleichheit) bedeutet:
a. Gleichheit für primitive Typen.
b. Identitätsprüfung für benutzerdefinierte Typen, daher sind wir gezwungen, die Funktion equals () für die Gleichheit zu verwenden.
Aber ... Was hat das mit Überlastung des Bedieners zu tun?
Wenn die Sprache eine Überlastung des Operators zulässt, kann der Benutzer dem Gleichheitsoperator die richtige Bedeutung geben.

Fernando Pelliccioni
quelle
Das Symbol ==wird in Java wie in C und C ++ für die Gleichheit verwendet. Dies hat nichts mit einer Überlastung des Bedieners zu tun.
Hot Licks
2
Der Operator == bedeutet in Java nur Gleichheit für primitive Typen. Für benutzerdefinierte Typen bedeutet Identität. In C ++ wird die Semantik vom Benutzer definiert, sollte jedoch die integrierte Semantik Gleichheit beibehalten. String a = "Hallo"; String b = "Hallo"; Boolescher Wert c = (a == b);
Fernando Pelliccioni
3
Was Sie in Ihrem ersten Kommentar gesagt haben, ist also falsch. Richtig? Bitte sagen Sie mir, wie Sie Gleichheit und Identität an benutzerdefinierten Typen in C testen können. Sie haben Recht, mein Kommentar zur Gleichheit ist OT, aber ich habe das klargestellt (siehe "Extras"). Die Tatsache, dass ich keine Programmiersprache erstellt habe, bedeutet nicht, dass ich eine vorhandene nicht kritisieren kann. Es tut mir leid, wenn Sie die Kritik als religiösen Krieg gesehen haben.
Fernando Pelliccioni
1
Um es kurz zu machen: Java ist scheiße.
Kolya Ivankov
12

Man kann Java Operator Overloading ausprobieren . Es hat seine eigenen Einschränkungen, aber es lohnt sich zu versuchen, wenn Sie wirklich die Operatorüberladung verwenden möchten.

Alexander Mironov
quelle
6

Verwenden Sie einfach Xtend zusammen mit Ihrem Java-Code. Es unterstützt das Überladen von Operatoren:

    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
    }

}

Auf der offiziellen Website finden Sie eine Liste der zu implementierenden Methoden für jeden Bediener!

Aurelien B.
quelle
5

Oder Sie können Java Groovy erstellen und diese Funktionen einfach überladen, um das zu erreichen, was Sie möchten

//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

Wer will nicht groovig sein / benutzen? : D.

Nein, Sie können die kompilierten groovigen JARs in Java nicht auf die gleiche Weise verwenden. Es ist immer noch ein Compilerfehler für Java.

weiß
quelle
1

Im Gegensatz zu C ++ unterstützt Java keine benutzerdefinierte Operatorüberladung. Das Überladen erfolgt intern in Java.

Wir können +zum Beispiel (plus) nehmen :

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

Hier fügt plus zwei Ganzzahlen hinzu und verkettet zwei Zeichenfolgen. Wir können also sagen, dass Java das Überladen interner Operatoren unterstützt, jedoch nicht benutzerdefiniert.

Nayanjyoti Sharma
quelle