2015-02-02 7 views
6

Come indicato in precedenza, here lambdas fornisce un modo abbastanza elegante di specificare il comportamento per i singoli valori enum.C'è qualche motivo per sovrascrivere i metodi in enumerazione in Java 8

Prima di Java 8 che normalmente hanno attuato questo come:

enum Operator { 
    TIMES { 
     public int operate(int n1, int n2) { 
      return n1 * n2; 
     } 
    }, 
    PLUS { 
     public int operate(int n1, int n2) { 
      return n1 + n2; 
     } 
    }; 

    public int operate(int n1, int n2) { 
     throw new AssertionError(); 
    }    
} 

Ora tendo a usare:

enum Operator { 
    TIMES((n1, n2) -> n1 * n2), 
    PLUS((n1, n2) -> n1 + n2); 

    private final BinaryOperator<Integer> operation; 

    private Operator(BinaryOperator<Integer> operation) { 
     this.operation = operation; 
    } 

    public int operate(int n1, int n2) { 
     return operation.apply(n1, n2); 
    } 
} 

Questo sembra molto più elegante.

Non riesco a pensare a un motivo per sovrascrivere i metodi per un valore enum specifico ora. Quindi la mia domanda è: ci sono dei buoni motivi per usare le sostituzioni dei metodi in un enum o dovrebbe sempre essere preferibile un'interfaccia funzionale?

+1

penso che dovrebbe essere 'int operate' pubblico nel primo codice ... –

+0

Si potrebbe avere molti metodi, chiamando l'un l'altro, in un enum. E la loro firma potrebbe non corrispondere a nessuna delle interfacce funzionali standard. A proposito, nel tuo primo frammento di codice, il tuo metodo operation() dovrebbe essere dichiarato astratto piuttosto che fornire un'implementazione. –

+0

Un altro modo (nell'esempio specifico) sarebbe 'enum Operator implementa BinaryOperator ' e quindi implementa 'apply' direttamente. –

risposta

5

Se si guarda a this answer che riassume i vantaggi di usare espressioni lambda in questo enum scenario che si potrebbe notare che questi vantaggi tutti scompaiono in 8 varianti-Java pre. Non è più leggibile della vecchia variante specializzata enum né migliora le prestazioni. Inoltre, lo interface BinaryOperator non esiste prima di Java 8, quindi è un'altra classe che dovrai aggiungere al tuo codebase per seguire questo approccio.

Il motivo principale per utilizzare questo approccio di delega in codice pre-Java 8 sarebbe quello di facilitare la migrazione se si prevede di passare a Java 8 al più presto.


aggiornamento alla tua domanda aggiornato:

Se ci si concentra principalmente sul caso Java 8 uso, mi sento di raccomandare di usare sempre l'approccio delegazione quando tutti i enum casi hanno un comportamento diverso che segue ancora un simile modello che può trarre vantaggio dall'utilizzo di espressioni lambda, come nel caso di implementazioni di operatori come nell'esempio.

Un controesempio sarebbe uno enum in cui la maggior parte di essi condivide un comportamento comune che verrà sovrascritto solo per uno o pochi casi. Es .:

enum Tokens { 
    FOO, BAR, BAZ, AND, A, LOT, MORE // etc … 

    /** Special Token End-Of-File */ 
    EOF { 
     @Override 
     public boolean matches(String input, int pos) { 
      return input.length()==pos; 
     } 
    }; 

    // all ordinary tokens have the same behavior 
    public boolean matches(String input, int pos) { 
     return input.length()-pos >= name().length() 
      && input.regionMatches(pos, name(), 0, name().length()); 
    } 
} 
+0

Grazie per questo. Non avevo trovato questa risposta prima di postare questo - non riesco davvero a cercare lavoro in SO! Detto questo, non sono sicuro che tu stia davvero rispondendo alla mia domanda. Non sto chiedendo se la nuova strada sia migliore (credo che lo sia) ma se ci sia qualche motivo per sovrascrivere i metodi nelle enumerazioni? – sprinter

+0

Ho modificato la domanda per rendere un po 'più chiaro quello che sto chiedendo. – sprinter

+0

Questa è una risposta ragionevole, ma il comportamento predefinito potrebbe essere implementato altrettanto facilmente con un costruttore vuoto che assegna al campo un lambda predefinito. – sprinter

Problemi correlati