2013-07-12 6 views
5

Stavo rifacendo del codice per renderlo più facile da leggere e mi sono imbattuto in qualcosa che trovavo strano e mi chiedevo se qualcuno potesse spiegarmi questo.Le variabili in casi di switch diversi non possono avere lo stesso nome?

Codice originale:

if(tokensLeft == 3) { 
    String id = tokens.nextToken(); 
    String value = tokens.nextToken(); 
    String trailerId = tokens.nextToken(); 
    rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this); 
} else if(tokensLeft == 2) { 
    String id = tokens.nextToken(); 
    String value = tokens.nextToken(); 
    rawListener.binaryInfo(id, Integer.parseInt(value), this); 
} else { 
    System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
} 

Dopo refactoring:

switch(tokensLeft) { 
case 3: 
    String id = tokens.nextToken(); 
    String value = tokens.nextToken(); 
    String trailerId = tokens.nextToken(); 
    rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this); 
    break; 
case 2: 
    String id = tokens.nextToken(); // Syntax error 
    String value = tokens.nextToken(); // Syntax error 
    rawListener.binaryInfo(id, Integer.parseInt(value), this); 
    break; 
default: 
    System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
    break; 
} 

A prima vista questo sembra perfettamente ragionevole, ma questo mi dà un errore di sintassi.

link tutti i riferimenti per una ridenominazione locale (non cambia i riferimenti in altri file)

Si scopre che per qualche ragione in un'istruzione switch, non sono in grado di utilizzare la String id e String value di nuovo in un altro caso.

Questo rende le variabili un po 'scomode.

Ora si potrebbe dire: "Basta dichiarare le variabili sopra l'istruzione switch". Ma ciò significherebbe che I sempre crea le mie variabili, anche se tokensLeft non è né 3 o 2 e non avrei bisogno delle mie variabili. Mi sembra di usare una memoria inutile.

Qualcuno può spiegarmi perché l'interruttore fa questo e come posso risolvere il mio problema?

+2

Utilizzare metodi - è buona pratica in ogni caso e il vostro campo di applicazione sarà ordinati per voi. Se vuoi davvero scrivere codice spaghetti, usa i blocchi espliciti ('{}'). –

risposta

1

Come non dichiarare le variabili?

switch (tokensLeft) { 
    case 3: 
     rawListener.binaryInfo(
       tokens.nextToken(), 
       parseInt(tokens.nextToken()), 
       tokens.nextToken(), 
       this); 
     break; 
    case 2: 
     rawListener.binaryInfo(
       tokens.nextToken(), 
       parseInt(tokens.nextToken()), 
       this); 
     break; 
    default: 
     throw new IllegalArgumentException("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
} 

ho aggiunto un import static per Integer.parseInt.

Meglio ancora chiamare la logica in metodi ben nominati dal switch e dichiarare qualunque cosa le variabili che si desidera:

public void parseTokens() { 
    switch (tokensLeft) { 
     case 3: 
      parseThreeTokens(rawListener, tokens); 
      break; 
     case 2: 
      parseTwoTokens(rawListener, tokens); 
      break; 
     default: 
      throw new IllegalArgumentException("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
    } 
} 

public void parseThreeTokens(final RawListener rawListener, final Tokens tokens) { 
    final String id = tokens.nextToken(); 
    final String value = tokens.nextToken(); 
    final String trailerId = tokens.nextToken(); 
    rawListener.binaryInfo(id, parseInt(value), trailerId, this); 

} 

public void parseTwoTokens(final RawListener rawListener, final Tokens tokens) { 
    final String id = tokens.nextToken(); 
    final String value = tokens.nextToken(); 
    rawListener.binaryInfo(id, parseInt(value), this); 
} 
+2

Suppongo che funzionerebbe, ma sembra rendere le cose meno facili da leggere quando il mio obiettivo originale è quello di renderlo più facile. – JREN

+0

In tal caso, creare metodi. Il tuo codice non è facile da leggere: la best practice (e lo zio Bob) suggerisce che i metodi non dovrebbero essere più lunghi di 10 righe. Questo interruttore è già quasi 20. –

+0

Hai qualche suggerimento su come posso differenziare tra i 2 metodi che creo perché l'unica differenza è che uno di loro userà un terzo parametro. A parte questo, sono identici. E i metodi accetterebbero entrambi solo 1 gettone 'paremeter'. – JREN

3

fare come qui sotto

String id; 
    String value ; 

    switch(tokensLeft) { 
    case 3: 
    id = tokens.nextToken(); 
    value = tokens.nextToken(); 
    String trailerId = tokens.nextToken(); 
    rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this); 
    break; 
    case 2: 
    id = tokens.nextToken(); // Syntax error 
    value = tokens.nextToken(); // Syntax error 
    rawListener.binaryInfo(id, Integer.parseInt(value), this); 
    break; 
    default: 
    System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
    break; 
    } 

Qui non causerà problemi di memoria come dici tu. Quando esegue il metodo manterrà id e value nello stack e nessun oggetto rilevante in heap per quei riferimenti. Quindi nessun problema con la memoria, invece la piccola memoria che prende per due ref.

+1

Si prega di leggere quello che ho detto sotto il mio codice ... – JREN

8

Si sta ridefinendo le variabili, ovvero la dichiarazione di variabili duplicate. case non fa un blocco.

Secondo JLS 14:

Un blocco è una sequenza di istruzioni, dichiarazioni di classi locali e istruzioni di dichiarazione variabili locali all'interno bretelle.

Hai due opzioni qui:

  1. definire un blocco esplicito sotto ogni caso utilizzando { .. }, anche se sembra piuttosto strano devo dire.

    O

  2. In ogni case è possibile delegare la logica per una chiamata di metodo.

+0

Ma come mi aiuta a risolvere il mio problema? – JREN

+3

È quindi possibile racchiudere la logica in una chiamata al metodo per ciascun caso? – NINCOMPOOP

+0

Beh, sì, lo vedo ora che hai modificato la tua risposta: p – JREN

6

aggiungi {}. provare questo:

switch(tokensLeft) { 
case 3: 
{ 
    String id = tokens.nextToken(); 
    String value = tokens.nextToken(); 
    String trailerId = tokens.nextToken(); 
    rawListener.binaryInfo(id, Integer.parseInt(value), trailerId, this); 
} 
    break; 
case 2: 
{ 
    String id = tokens.nextToken(); // Syntax error 
    String value = tokens.nextToken(); // Syntax error 
    rawListener.binaryInfo(id, Integer.parseInt(value), this); 
} 
    break; 
default: 
    System.out.println("Method call binaryInfo could not be done because: \"Wrong number of parameters\""); 
    break; 
} 
+0

piuttosto intelligente. questa dovrebbe essere la risposta giusta. raggiunge l'obiettivo dell'op di usare lo stesso nome di variabile in più casi di switch. – Thupten

2

È possibile utilizzare le parentesi graffe {} dopo il caso:

int aInt = 3; 
switch (aInt) { 
    case 0: { 
    String text = ""; 
    break; 
    } 
    case 1: { 
    String text = ""; 
    break; 
    } 
} 
0

case in switch informazioni non sono blocks; quindi, dichiarando la stessa variabile in più casi di switch, si sta tentando di ridefinire la variabile. Funziona nelle istruzioni if perché formano blocks.

Dichiararli prima dell'interruttore o inserire blocchi nei casi.