Java non supporta il sovraccarico diretto degli operatori come avviene, ad esempio, in C++. Storicamente, questa limitazione è stata introdotta per semplificare la lettura del codice e ridurre le ambiguità: Bjarne Stroustrup (il creatore di C++) e James Gosling (il creatore di Java) hanno discusso su questo argomento, e in Java è stata presa la decisione di non permettere agli sviluppatori di definire un comportamento personalizzato degli operatori per le proprie classi.
Il problema del sovraccarico degli operatori è che una libertà eccessiva nel definire l'aritmetica e la logica per le classi personalizzate può portare a bug difficili da tracciare e a una lettura del codice compromessa, specialmente in grandi team.
La soluzione è vietare il sovraccarico degli operatori da parte degli utenti. Tuttavia, Java supporta all'interno delle proprie classi il sovraccarico dei metodi e il comportamento degli operatori può essere simulato tramite metodi esplicitamente definiti (ad esempio, .add(), .equals(), .compareTo(), ecc.).
Esempio di codice:
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); // invece di v1 + v2
Caratteristiche chiave:
Si può sovraccaricare l'operatore "+" in Java per la propria classe per sommare oggetti?
Risposta: No, Java non supporta il sovraccarico personalizzato degli operatori aritmetici per le classi create dagli utenti. L'eccezione è fatta solo per le stringhe: l'operatore "+" chiama la concatenazione tramite StringBuilder.
Se viene definito il metodo equals(), l'operatore "==" funzionerà come confronto dei valori?
Risposta: No, l'operatore "==" confronta i riferimenti agli oggetti, non il loro contenuto. Per un confronto corretto dei valori si utilizza equals() sovrascritto.
String a = new String("hello"); String b = new String("hello"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true
Ci sono eccezioni in cui l'operatore standard si comporta in modo particolare per classi non standard?
Risposta: Un comportamento "particolare" in Java è implementato solo per String con l'operatore "+" e per i tipi primitivi (promozione automatica e unboxing). Per le altre classi, gli operatori si comportano in modo standard (ovvero non sono sovraccaricati).
Un giovane sviluppatore ha scritto una classe Money e ha iniziato a confrontare due oggetti tramite "==", pensando che si confrontassero per i valori. Questo ha portato a errori nel controllo di uguaglianza, che si sono manifestati solo in produzione.
Vantaggi:
Svantaggi:
Nel progetto è stata scritta la propria classe Vector, tutte le operazioni aritmetiche sono state implementate esplicitamente, l'operatore == non è utilizzato per gli oggetti e la documentazione descrive la semantica del lavoro dei metodi.
Vantaggi:
Svantaggi: