Surcharge des opérateurs en Java

Réponses:

235

Non, Java ne prend pas en charge la surcharge d'opérateurs définis par l'utilisateur. Le seul aspect de Java qui se rapproche de la surcharge d'opérateurs "personnalisés" est la gestion de + pour les chaînes, ce qui entraîne soit une concaténation de constantes au moment de la compilation, soit une concaténation au moment de l'exécution à l'aide de StringBuilder / StringBuffer. Vous ne pouvez pas définir vos propres opérateurs qui agissent de la même manière.

Pour un langage de type Java (et basé sur JVM) qui prend en charge la surcharge d'opérateurs, vous pouvez regarder Kotlin ou Groovy . Alternativement, vous pourriez trouver de la chance avec une solution de plugin de compilateur Java .

Jon Skeet
la source
4
Vous dites que nous ne pouvons pas créer un wrapper en java? Tels que SmallInteger comme Integer?
huseyin tugrul buyukisik
3
@ tuğrulbüyükışık: Il existe déjà des wrappers pour tous les types primitifs existants - mais si vous vouliez créer votre propre nouveau type de wrapper, vous ne pourriez pas le faire se comporter comme les autres, car ils ont un support spécifique dans le langage.
Jon Skeet
1
merci, j'ai cherché sur Google et je n'ai pas pu trouver. Je voulais savoir si je pouvais créer une variable complexe composée de deux primitives (un double et un int ---> bonne précision + bonne plage)
huseyin tugrul buyukisik
40
@djaqeel: La surcharge des opérateurs rend le code moins lisible lorsqu'il est mal utilisé . Lorsqu'il est bien utilisé, il peut grandement améliorer la lisibilité de l'OMI. Regardez le code qui utilise BigIntegeren Java, puis regardez du code similaire en utilisant BigIntegeren C # à l'aide d'opérateurs. Je ne vois pas comment les délégués enfreignent les principes de la POO - vous devez être beaucoup plus précis que cela dans vos objections. Je ne connais pas les détails sur les raisons pour lesquelles les concepteurs Java n'ont pas inclus diverses fonctionnalités, mais je soupçonne qu'il y a un mélange de pression sur les ressources et un désir de garder le langage petit et relativement simple.
Jon Skeet
4
Je sais que c'est tard, mais un exemple vaut mille arguments. Compte tenu m0comme Matrixet v0, v1, v2, v3et v4comme Vectors, il suffit de comparer combien de temps il vous faut pour bien interpréter l'expression mathématique suivante m0.transpose().mult(v0.add(v1.mult(v2)).cross(v3)).sub(v4);. Si la prise en charge de la surcharge des opérateurs avait été incluse, cela aurait pu être écrit sous la forme m0.transpose() * (v0 + v1 * v2).cross(v3) - v4;.
code_dredd
38

La surcharge d'opérateur est utilisée en Java pour la concaténation du type String:

String concat = "one" + "two";

Cependant, vous ne pouvez pas définir vos propres surcharges d'opérateurs.

teabot
la source
26

En plus de toutes les personnes soulignant qu'il +est surchargé pour les chaînes, -est également surchargé pour les opérations à virgule flottante et entière, comme le sont *et /.

[edit] %est également surchargé pour la virgule flottante, ce qui peut être un peu une surprise pour ceux qui ont un fond C ou C ++.

MSalters
la source
21

Java n'autorise pas la surcharge des opérateurs. L'approche préférée est de définir une méthode sur votre classe pour effectuer l'action: a.add(b)au lieu de a + b. Vous pouvez voir un résumé des autres bits Java laissés de côté des langages de type C ici: Fonctionnalités supprimées de C et C ++

Rob
la source
2
L'important est l'objectif de conception de rendre les fichiers source Java indépendants du contexte. Essayer de lire de très grands programmes (MLOC), macro lourds C a une très longue courbe d'apprentissage. Un programme Java comparable (ou plus grand) n'est pas plus difficile à utiliser qu'un petit programme Java. Comme Gosling l'a dit: Un langage pour les programmeurs de cols bleus pour travailler. [Et quiconque pense que la verbosité passe-partout est préjudiciable devrait lire sur la segmentation dans la cognition experte.]
Tim Williscroft
2
Grâce à oracle, aucun des liens java.sun.com ne fonctionne. Pouvez-vous s'il vous plaît donner le lien mis à jour, si possible?
Syed Aqeel Ashiq
17

Vous ne pouvez pas le faire vous-même car Java n'autorise pas la surcharge des opérateurs.

À une exception près, cependant. + et + = sont surchargés pour les objets String.

Brian Agnew
la source
8
Il existe de nombreux autres exemples de surcharge d'opérateurs en Java. Par exemple &, |et ^sont des surcharges pour booleanet des types intégraux. Et en effet, les opérateurs arithmétiques et relationnels sont surchargés pour différents types numériques. (Bien sûr, la sémantique des surcharges est beaucoup plus proche ...)
Stephen C
16

Comme beaucoup d'autres l'ont répondu: Java ne prend pas en charge la surcharge d'opérateurs définis par l'utilisateur.

C'est peut-être hors sujet, mais je veux faire des commentaires sur certaines choses que j'ai lues dans certaines réponses.

À propos de la lisibilité.
Comparer:

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

Regarde encore!
Lequel est le plus lisible?

Un langage de programmation qui permet la création de types définis par l'utilisateur, devrait leur permettre d'agir de la même manière que les types intégrés (ou types primitifs).

Ainsi, Java rompt un principe fondamental de la programmation générique:
nous devrions être capables d'échanger des objets de types intégrés avec des objets de types définis par l'utilisateur.
(Vous vous demandez peut-être: "A-t-il dit 'objets intégrés'?". Oui, voir ici .)

À propos de la concaténation de chaînes:

Les mathématiciens utilisent le symbole + pour les opérations commutatives sur les ensembles.
Nous pouvons donc être sûrs que a + b = b + a.
La concaténation de chaînes (dans la plupart des langages de programmation) ne respecte pas cette notation mathématique courante.

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

ou en Java:

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

Extra:
Remarquez comment, en Java, l'égalité et l'identité sont confondues. Le symbole == (égalité) signifie:
a. Égalité pour les types primitifs.
b. Vérification d'identité pour les types définis par l'utilisateur, par conséquent, nous sommes obligés d'utiliser la fonction equals () pour l'égalité.
Mais ... Qu'est-ce que cela a à voir avec la surcharge des opérateurs?
Si le langage permet à l'opérateur de surcharger, l'utilisateur pourrait donner le sens approprié à l'opérateur d'égalité.

Fernando Pelliccioni
la source
Le symbole ==est utilisé pour l'égalité en Java, comme en C et C ++. Cela n'a rien à voir avec la surcharge des opérateurs.
Hot Licks
2
L'opérateur ==, en Java, signifie uniquement l'égalité pour les types primitifs. Pour les types définis par l'utilisateur signifie Identité. En C ++, la sémantique est définie par l'utilisateur, mais doit préserver la sémantique intégrée, l'égalité. String a = "bonjour"; String b = "bonjour"; booléen c = (a == b);
Fernando Pelliccioni
3
Donc ce que vous avez dit dans votre premier commentaire est faux. Droite? S'il vous plaît, dites-moi comment tester l'égalité et l'identité sur les types définis par l'utilisateur en C. Vous avez raison, mon commentaire sur l'égalité est OT, mais j'ai clarifié cela (voir les "extras"). Le fait que je n'ai pas créé de langage de programmation ne signifie pas que je ne peux pas critiquer un langage existant. Je suis désolé si vous avez vu la critique comme une guerre religieuse.
Fernando Pelliccioni du
1
Bref, java est nul.
Kolya Ivankov
12

On peut essayer la surcharge d'opérateur Java . Il a ses propres limites, mais cela vaut la peine d'essayer si vous voulez vraiment utiliser la surcharge d'opérateurs.

Alexandre Mironov
la source
6

Utilisez simplement Xtend avec votre code Java. Il prend en charge la surcharge de l'opérateur:

    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
    }

}

Sur le site officiel, il y a une liste des méthodes à mettre en œuvre pour chaque opérateur!

Aurélien B
la source
5

Ou, vous pouvez créer Java Groovy et simplement surcharger ces fonctions pour obtenir ce que vous voulez

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

Qui ne veut pas être / utiliser groovy? :RÉ

Non, vous ne pouvez pas utiliser les JAR groovy compilés en Java de la même manière. Il s'agit toujours d'une erreur de compilation pour Java.

sait
la source
1

Contrairement à C ++, Java ne prend pas en charge la surcharge d'opérateurs définis par l'utilisateur. La surcharge se fait en interne en java.

On peut prendre +(plus) par exemple:

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

Ici, plus ajoute deux nombres entiers et concatène deux chaînes. Nous pouvons donc dire que Java prend en charge la surcharge des opérateurs internes mais pas celle définie par l'utilisateur.

nayanjyoti sharma
la source