Passa senza interruzioni

Ho alcune istruzioni sull’interruttore come mostrato di seguito. Si noti che non c’è alcuna interruzione. Findbugs sta segnalando un errore solo nella seconda frase. L’errore è: l’istruzione switch è stata individuata dove un caso passa al caso successivo.

switch(x) { case 0: // code case 1: // code case 2: // code } 

Findbugs segnala che passare da un case all’altro non è generalmente una buona idea se c’è un codice nel primo (anche se a volte può essere usato con buoni risultati). Quindi, quando vede il secondo case e nessuna break , segnala l’errore.

Quindi per esempio:

 switch (foo) { case 0: doSomething(); case 1: doSomethingElse(); default: doSomeOtherThing(); } 

Questo è Java perfettamente valido, ma probabilmente non fa ciò che l’autore intendeva: Se foo è 0 , tutte e tre le funzioni eseguono doSomeOtherThing , doSomethingElse e doSomeOtherThing (in questo ordine). Se foo è 1 , doSomeOtherThing eseguiti solo doSomethingElse e doSomeOtherThing . Se foo è un qualsiasi altro valore, doSomeOtherThing eseguito solo doSomeOtherThing .

In contrasto:

 switch (foo) { case 0: doSomething(); break; case 1: doSomethingElse(); break; default: doSomeOtherThing(); break; } 

Qui, verrà eseguita solo una delle funzioni, a seconda del valore di foo .

Poiché si tratta di un errore di codifica comune per dimenticare l’ break , strumenti come Findbugs lo segnalano per te.

C’è un caso d’uso comune in cui si hanno più istruzioni case in fila senza codice intermedio:

 switch (foo) { case 0: case 1: doSomething(); break; case 2: doSomethingElse(); break; default: doSomeOtherThing(); break; } 

Lì, vogliamo chiamare doSomething se foo è 0 o 1 . La maggior parte degli strumenti non contrassegnerà questo come un ansible errore di codifica, perché non c’è codice nel case 0 prima del case 1 e questo è uno schema abbastanza comune.

Li ho scritti come commenti ma poi non è visibile. Li sto trasformando in una risposta. Questa è in realtà un’estensione della risposta di TJCrowder .

Puoi trovare la regola correlata che fa sì che Findbugs segnali un errore qui .

Puoi impedire a Findbug di segnalare questo tipo di errori creando un file xml con il seguente contenuto, ad esempio filter.xml ed eseguendo lo strumento con l’opzione -exclude filter.xml . Guarda i filtri su Findbugs .

      

Passare i fall-through rientrano nella categoria Findbugs di “codice dodgy”. Penso che contrassegna solo la prima occorrenza di un fall-through in un’istruzione switch per ridurre il numero di messaggi di errore.

Senza la pausa cadranno però l’una nell’altra, quindi se x == 0 passerai attraverso tutto il codice in ogni blocco di istruzioni. Findbug potrebbe essere sbagliato sull’errore, o potrebbe essere una condizione di errore senza interruzione, cioè qualcosa nel case 0 causasse qualcosa nel case 1 di rompere.

Senza il codice esatto e l’errore non posso davvero aiutare ulteriormente. La mancanza di pause è intenzionale?

Solitamente gli strumenti per l’analisi dei bug non gradiscono la ricaduta nel codice perché nella maggior parte dei casi l’utente ha appena dimenticato di scrivere la pausa.

Non so se esiste un modo per distriggersre specificamente l’avviso con FindBugs ma lo strumento Checkstyle riconosce i commenti speciali come / * di passaggio * / per assumere che l’utente desideri davvero che venga eseguito il codice seguente. Mettere questo tipo di commento migliora anche la leggibilità. http://checkstyle.sourceforge.net/config_coding.html#FallThrough

La convenzione del codice Java menziona anche l’uso del commento di fallthrough. http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html

Se i casi non hanno interruzione, una volta che un caso è triggersto, il passaggio passerà attraverso tutti i casi fino a quando non troverà una rottura o una fine dei casi. Se hai un caso predefinito, si innescherà se il tuo valore di switch in questo caso pippo non corrisponde a nessun altro caso.