Qual è il vantaggio dell'attivazione di String in Java 7?

19

Quando stavo iniziando a programmare in Java, il fatto che le istruzioni switch non prendessero stringhe mi ha frustrato. Poi, usando Enums, ho compreso i vantaggi che si ottengono con loro piuttosto che passare intorno ai valori non elaborati - digitare safety (che facilita il refactoring) & anche chiarezza con altri sviluppatori.

Sto faticando a pensare a una situazione in cui con SE7 ora deciderò di utilizzare uno switch con stringhe come input anziché Enums. Se vengono implementati tramite l'attivazione di intere stringhe (ad esempio anziché le corrispondenze parziali o regolari), non sembra offrire meno motivi per la modifica del codice.

E con gli strumenti IDE e il rapporto lettura-scrittura della codifica, sarei molto più felice di generare automaticamente un Enum extra rispetto al passaggio di valori stringa.

Quali vantaggi ci offrono come programmatori? Meno piastra della caldaia?

Non sembra che la lingua stia piangendo per questa funzione. Anche se forse c'è un caso d'uso che sto trascurando.

    
posta anotherdave 16.11.2013 - 19:51
fonte

8 risposte

12

Per quello che posso dire, la domanda è perché il wrapping delle costanti String in enum non è stato considerato sufficiente per coprire le esigenze degli utenti di lingue. Questo problema è stato risolto nella proposta di funzione ufficiale annunciata a JDK 7 ( mailing list project.

Secondo la mia lettura della proposta, l'alternativa all'uso dell'enumerazione è stata respinta in quanto introduce tipi rigonfiati. Per tua comodità, la parte pertinente della proposta è riportata di seguito, con la dichiarazione che riporta enumerazioni citate in grassetto :

MAJOR ADVANTAGE: What makes the proposal a favorable change?

More regular coding patterns can be used for operations selected on the basis of a set of constant string values; the meaning of the new construct should be obvious to Java developers.

MAJOR BENEFIT: Why is the platform better if the proposal is adopted?

Potentially better performance for string-based dispatch code.

MAJOR DISADVANTAGE: There is always a cost.

Some increased implementation and testing complexity for the compiler.

ALTERNATIVES: Can the benefits and advantages be had some way without a language change?

No; chained if-then-else tests for string equality are potentially expensive and introducing an enum for its switchable constants, one per string value of interest, would add another type to a program without good cause...

    
risposta data 18.11.2013 - 09:06
fonte
7

Oltre a rendere il codice più leggibile, ci sono potenziali guadagni in termini di prestazioni rispetto ai confronti con if/else if . Se il cambiamento è utile dipende da quanti confronti si stanno facendo. Un interruttore di stringa verrà emesso come due istruzioni di commutazione separate. Il primo funziona con i codici hash, quindi tende ad essere un lookupswitch , che alla fine produce una O(log n) complessità. Il secondo è sempre un perfetto O(1) tableswitch , quindi la complessità combinata è ancora O(log n) . Una singola catena lineare di istruzioni if/else if darebbe un po 'meno peggio di O(n) complessità.

Se stai confrontando più di, per esempio, tre stringhe, allora switch è probabilmente più leggibile e compatto. Probabilmente funzionerà meglio, anche se è improbabile notare una differenza a meno che non si stia facendo un gran numero di confronti su un percorso di hot code.

    
risposta data 16.11.2013 - 20:07
fonte
3

È possibile utilizzare lo switch per le stringhe quando i valori enum provengono dall'esterno, ovvero memorizzati in un database.

Un'altra cosa degna di nota in JDK 7% diswitch è che è molto più perfomante dei costrutti if-else .

E un buon caso d'uso per la stringa veloce switch es potrebbe essere l'analisi del flusso JSON / XML quando è necessario eseguire molti switch sul nodo e sui tipi di attributi. Non riesco a pensare ad alcuna opzione migliore per questo.

    
risposta data 16.11.2013 - 20:04
fonte
2

Semplicità

Le stringhe nel supporto Switch sono utili per l'elaborazione dei dati senza conversione in enum o if-else logic. A volte è più semplice attivare String.

Da proposta di funzionalità alla mailing list JDK 7 (project Coin) ( risposta @gnat )

introducing an enum for its switchable constants, one per string value of interest, would add another type to a program without good cause...

Versione If-Else

Questo è breve, ma molti if's sono difficili da leggere. E questo è lento.

if (color.equals("red")) {
    System.out.println("Color is Red");
} else if (color.equals("green")) {
    System.out.println("Color is Green");
} else {
    System.out.println("Color not found");
}

Versione Enum

Le enumerazioni devono essere definite, questo è buono, ma a volte non è necessario.

enum Color {RED, GREEN}

Elaborazione come al solito

try {
    switch (Color.valueOf(color)) {
        case RED:
            System.out.println("Color is Red");
            break;
        case GREEN:
            System.out.println("Color is Green");
            break;
    }
} catch (IllegalArgumentException e) {
    System.out.println("Color not found");
}

JDK 7 - Stringhe nella versione delle istruzioni switch

Possiamo elaborare senza convertire e definire tipi aggiuntivi.

switch (color) {
    case "red":
        System.out.println("Color is Red");
        break;
    case "green":
        System.out.println("Color is Green");
        break;
    default:
        System.out.println("Color not found");
}
    
risposta data 16.11.2013 - 20:00
fonte
0

La maggior parte dei miglioramenti in qualsiasi lingua servono a rendere il codice più facile da leggere. Preferisco il codice leggibile ogni giorno.

Potresti non crederci, ma prova:

public enum JettStaff {
  ADRIAN("Adrian German") {
    public String toString() {
      return name + " ([email protected])";
    }
  },
  ARJIT("Arjit Sengupta") {
    public String toString() {
      return name + " ([email protected])";
    }
  },

  // and on for the rest...

  private String name;

  public JettStaff(String n) { this.name = n; }
}

JettStaff x = JettStaff.SUZANNE;
System.out.println(x);
    
risposta data 16.11.2013 - 19:56
fonte
0

Le enumerazioni sono grandiose e dovresti usare quelle al posto delle stringhe quando hai la capacità di farlo. Ma ci sono delle volte in cui non ci riuscivate, per esempio quando è necessario lavorare con qualche oggetto esterno proveniente da Java. Immagina di dover analizzare qualcosa. Come la risposta del server, la configurazione, il file di registro o qualcosa di simile: hai un sacco di opzioni che stai cercando e non c'è modo che queste possano essere enumerazioni. Quindi in Java < 7 saresti bloccato con un mucchio di

  if (something.equals("foo")) {
    // foo processing
  } else 
  if (something.equals("bar")) {
   // bar processing
  }

In questo caso puoi ancora usare le enumerazioni semplicemente cercando di ottenere quelle per nome e / o fornendo una routine personalizzata String- > Enum ma a volte non è possibile o semplicemente non pratica (cioè quando dovresti creare anche tu molte enumerazioni)

TLDR : devi assolutamente usare Enums quando lavori con codice Java, ma non è sempre possibile con oggetti esterni. Spero che la mia spiegazione abbia un senso.

    
risposta data 16.11.2013 - 20:07
fonte
0

Non sono d'accordo con l'opinione che sia un codice più chiaro e leggibile quando si utilizza Strings nelle istruzioni switch e si pensa che sia una cattiva pratica di programmazione. Se si modifica il valore che si utilizza per memorizzare, è necessario modificarlo ogni interruttore o se-altrimenti occorrenza. Questo non va bene dato che stai mettendo valori hardcoded su ogni bir del tuo codice. Che cosa hai intenzione di fare se un giorno decidessi di cambiare uno di questi valori codificati? Cerca e sostituisci ogni copia di esso?

Se hai alcuni valori hardcoded che fai le istruzioni if-elseif, usando valori costanti primitivi per loro è molto meglio prima di Java 1.5 solo perché porta la sicurezza del tipo.

OK, ci saranno situazioni in cui otterrai valori di stringa (da richiesta HTTP, file ecc.) e convertirli ai valori primitivi è un granello di dolore. Ma Enum s fa un buon lavoro a questo punto. Perché quando vuoi cambiare il valore che immagazzini in Enum, cambialo quando lo dichiari. Non è necessario cambiare nient'altro nel tuo codice. (Ovviamente è necessario modificare i valori memorizzati da qualche altra parte).

Se stai implementando un codice sporco e pigro, è perfetto. Non vuoi coinvolgere per codificare un sacco di Enum s, ma in un software complesso su larga scala che ti ucciderà.

    
risposta data 16.11.2013 - 20:09
fonte
-1

Se sai quali informazioni arrivano e che potrebbero essere solo di 5 stati, usa Enum . Tuttavia, se gli stati possibili potrebbero essere superiori a 9000 e devi solo trovare 42, l'utilizzo di un interruttore è migliore perché non vuoi digitare tutti quegli stati.

Un Enum tende ad essere la scelta più nella maggior parte delle circostanze a meno che i possibili stati siano sconosciuti o ce ne siano molti e a te interessa solo pochi.

Ma perché l'hanno introdotto adesso? Era solo un cambiamento che permetteva un codice più pulito.

Nella 1.5 hanno permesso anche di creare corpi personalizzati per Enum.

    
risposta data 16.11.2013 - 20:18
fonte

Leggi altre domande sui tag