2009-11-06 10 views
126

La prego di dirmi se è possibile sovraccaricare gli operatori in Java? Se è usato da qualche parte in Java, potresti dirmi a riguardo.Sovraccarico dell'operatore in Java

+0

Possibile duplicato di [Perché Java non offre l'overloading dell'operatore?] (Https://stackoverflow.com/questions/77718/why-doesnt-java-offer-operator-overloading) –

risposta

180

No, Java non supporta l'overloading dell'operatore definito dall'utente. L'unico aspetto di Java che si avvicina all'overloading "personalizzato" dell'operatore è la gestione di + per le stringhe, che risulta nella concatenazione in tempo di compilazione delle costanti o nella concatenazione del tempo di esecuzione utilizzando StringBuilder/StringBuffer. Non è possibile definire i propri operatori che agiscono allo stesso modo però.

Per un linguaggio Java (e basato su JVM) che supporta per l'overloading dell'operatore, è possibile consultare Groovy. In alternativa, potresti trovare fortuna con uno Java compiler plugin solution.

+3

Stai dicendo che non possiamo creare wrapper in java? Come SmallInteger come Integer? –

+1

@ tuğrulbüyükışık: Esistono già wrapper per tutti i tipi primitivi esistenti, ma se volessi creare il tuo nuovo tipo di wrapper, non saresti in grado di farlo funzionare come gli altri, in quanto hanno un supporto specifico nella lingua . –

+1

grazie, ho cercato su Google e non ho potuto trovare. Volevo sapere se potevo creare una variabile complessa composta da due primitive (una doppia e una int ---> buona precisione + buona gamma) –

14

Non è possibile eseguire questa operazione poiché Java non consente il sovraccarico dell'operatore.

Con un'eccezione, tuttavia. + e + = sono sovraccaricati per gli oggetti String.

+0

Downvoted perché? –

+5

Esistono molti altri esempi di overloading degli operatori in Java. Ad esempio '&', '|', e '^' sono sovraccarichi per tipi 'boolean' e interi. E infatti, gli operatori aritmetici e relazionali sono sovraccaricati per vari tipi numerici. (Naturalmente, la semantica dei sovraccarichi è molto più vicina ...) –

29

overloading degli operatori è utilizzato in Java per la concatenazione di tipo String:

String concat = "one" + "two"; 

Tuttavia, non sipossibile definire i propri overload dell'operatore.

14

Java non consente il sovraccarico dell'operatore. L'approccio preferito consiste nel definire un metodo sulla classe per eseguire l'azione: a.add(b) anziché a + b. È possibile visualizzare un riepilogo degli altri bit Java lasciato fuori dalla C come le lingue qui: Features Removed from C and C++

+0

Link interessante – Wernsey

+2

L'importante è l'obiettivo di design di rendere indipendenti i file di origine Java. Cercando di leggere molto grandi (MLOC), i programmi di macro pesante C hanno una curva di apprendimento molto lunga. Un programma Java paragonabile (o più grande) non è più difficile da immergere rispetto a un piccolo programma Java. Come ha detto Gosling: un linguaggio per i programmatori di operai in cui lavorare. [E chiunque pensi che la verbosità di boilerplate sia dannosa dovrebbe leggere qualcosa sulla cognizione esperta.] –

+1

Grazie a oracle, nessuno dei collegamenti java.sun.com funziona. Puoi per favore dare il link aggiornato, se possibile? –

20

In aggiunta a tutte le persone che indicano che + è sovraccarico per archi, - è anche sovraccarico sia per le operazioni in virgola mobile e ad interi, così come lo sono * e /.

[modifica] % è anche sovraccarico per il punto mobile, che può essere un po 'una sorpresa per quelli con uno sfondo C o C++.

10

Si può provare Java Operator Overloading. Ha i suoi limiti, ma vale la pena provare se si vuole veramente usare l'overloading dell'operatore.

+0

Oppure [light/JOps] (https://github.com/light/JOps) –

6

Basta usare Xtend insieme al codice Java. Esso supporta l'overloading degli operatori:

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 
    } 

} 

Sul sito ufficiale, c'è una lista dei metodi per implementare per ogni operatore!

5

In alternativa, è possibile rendere Java Groovy e proprio sovraccaricare queste funzioni per ottenere quello che vuoi

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

Chi non vuole essere/usare Groovy? : D

No, non è possibile utilizzare i JAR groovy compilati in Java allo stesso modo. È ancora un errore del compilatore per Java.

6

Come molti altri hanno risposto: Java non supporta l'overloading dell'operatore definito dall'utente.

Forse questo è fuori tema, ma voglio commentare alcune cose che ho letto in alcune risposte.

Informazioni sulla facilità di lettura.
Confronta:

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

guardare di nuovo!
Quale è più leggibile?

Un linguaggio di programmazione che consente la creazione di tipi definiti dall'utente, dovrebbe consentire loro di agire allo stesso modo dei tipi predefiniti (o tipi primitivi).

Così Java rompe un principio fondamentale della programmazione generica:
dovremmo essere in grado di scambiare oggetti di tipi built-in con oggetti di tipi definiti dall'utente.
(Ci si potrebbe chiedere: "Ha detto 'oggetti di built-in'?" Sì, see here..)

A proposito di concatenazione di stringhe:

I matematici usano la symnol + per commutativa operazioni sui set.
Quindi possiamo essere sicuri che a + b = b + a.
La concatenazione di stringhe (nella maggior parte dei linguaggi di programmazione) non rispetta questa notazione matematica comune.

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

o in Java:

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

Extra:
Notare come in Java uguaglianza e identità sono confusi. Il simbolo == (uguaglianza) significa:
a. Uguaglianza per i tipi primitivi
b. Identity-check per i tipi definiti dall'utente, pertanto, siamo obbligati a utilizzare la funzione equals() per l'uguaglianza.
Ma ... Cosa c'entra questo con il sovraccarico dell'operatore?
Se la lingua consente il sovraccarico dell'operatore, l'utente può dare il significato corretto all'operatore di uguaglianza.

+0

Il simbolo '==' viene utilizzato per l'uguaglianza in Java, come in C e C++. Questo non ha nulla a che fare con il sovraccarico dell'operatore. –

+2

L'operatore ==, in Java indica Equality solo per i tipi primitivi. Per tipi definiti dall'utente significa Identità. In C++ la semantica è definita dall'utente, ma dovrebbe preservare la semantica integrata, l'uguaglianza. String a = "ciao"; Stringa b = "ciao"; booleano c = (a == b); –

+0

Sì, proprio come in C, che Java ha copiato. Il tuo rant parla di Java in generale e non ha nulla a che fare con il fatto * che Java non supporta l'overloading dell'operatore. Quando crei la tua lingua, puoi definirla nel modo desiderato. –