Potrebbe Java XYZ implementare (limitato) il sovraccarico dell'operatore senza compromettere la retrocompatibilità?

0

Recentemente, ho imparato un po 'più di C ++ e i pericoli e gli usi dell'overloading dell'operatore, e il miglioramento della leggibilità che fornisce ai tipi aritmetici (come i numeri complessi).

Qualche tempo fa, stavo giocando con Rust, e mi piaceva molto il modo in cui gestivano il sovraccarico dell'operatore, cioè tramite Tratti nella cassa std::ops . Quindi, avendo:

struct Fraction {
  numerator: i32,
  denominator: i32,
}

impl Add for Fraction { /* ... */ }

Termina sovraccarico dell'operatore + . Questo mi porta a chiedermi l'argomento del titolo ...

È possibile che Java implementi un numero limitato di overload degli operatori tramite interfacce? Il compilatore può verificare se la classe del chiamante implementa l'interfaccia per un determinato operatore e cambiare l'operatore in una chiamata al metodo (quindi, essendo tutto sintassi zucchero) o non riuscendo a compilare altrimenti.

Questo implicherebbe la rottura delle modifiche per il codice compilato nelle versioni precedenti? Qualcuno sa se questo è già stato discusso nella mailing list o un JEP proposto?

    
posta Alxe 19.05.2016 - 19:06
fonte

2 risposte

7

La risposta alla tua domanda è piuttosto semplice: compatibilità con le versioni precedenti significa non modificare il significato del codice esistente. Dato che non esiste un codice esistente che utilizza operatori definiti dall'utente, poiché gli operatori definiti dall'utente non esistono , l'introduzione di questi non può interrompere la compatibilità all'indietro.

Foo a = new Foo();
Foo b = new Foo();

Foo c = a + b;

Tale codice non può essere scritto oggi.

L'implementazione più semplice dell'overloading dell'operatore sarebbe semplicemente quella di renderli metodi. Per es.

class Fraction {
  int numerator, denominator;

  public Fraction *(Fraction other) {
    return new Fraction(numerator * other.numerator, denominator * other.denominator);
  }
}

Poiché tali nomi sono attualmente illegali, la compatibilità con le versioni precedenti è preservata: al momento non esiste un codice che utilizza questi nomi e il cui significato potrebbe cambiare. Se si implementa uno schema di maneggevolezza dei nomi per questi metodi, si potrebbe anche andare avanti senza modificare i formati bytecode e classfile, quindi il codice che viene compilato con un compilatore JavaXYZ verrà comunque eseguito su Java 8.

Questa è la soluzione più semplice possibile. Se vuoi qualcosa di più sofisticato, come definire la fissità, l'associatività e la precedenza degli operatori, dovrai fare più lavoro. In particolare, l'analisi è (un po ') complicata: devi sapere se è left-associatice o right-associative prima di poter analizzare correttamente a ∪ b ∪ c , ad esempio. Quindi devi analizzare le definizioni degli operatori importati prima di poter analizzare il codice.

    
risposta data 19.05.2016 - 21:30
fonte
1

Romperebbe il codice esistente se fosse possibile sovrascrivere il confronto == o anche = assegnazione. == è usato per confrontare gli indirizzi di memoria di due oggetti, indipendentemente da ciò che dice il loro metodo equals() . == è anche true per due oggetti null . Non voglio immaginare cosa succede se gli oggetti sono autorizzati a sovrascrivere = operatore di assegnazione.

    
risposta data 20.05.2016 - 09:41
fonte

Leggi altre domande sui tag