È buona norma utilizzare gli avvisi di soppressione nel codice?


11

Io uso @SuppressWarnings("unchecked")e @SuppressWarnings("null")per lo più al di sopra metodi di lasciare che il codice di compilazione senza avvisi, ma ho i miei dubbi. Ho trovato questa domanda StackOverflow . Jon Skeet ha scritto una risposta che trovo intrigante.

Secondo lui,

A volte i generici Java non ti consentono di fare ciò che vuoi e devi dire efficacemente al compilatore che ciò che stai facendo sarà veramente legale al momento dell'esecuzione.

E se ci fosse la possibilità che venga generata un'eccezione? La soppressione degli avvisi non è quindi una cattiva idea? Non dovrei essere consapevole dei luoghi in cui i problemi potrebbero emergere?

Inoltre, cosa succede se qualcun altro modifica il mio codice in un secondo momento e aggiunge alcune funzionalità discutibili senza rimuovere SuppressWarnings? Come può essere evitato e / o c'è qualche altra alternativa a questo?

Dovrei usare @SuppressWarnings("unchecked")e @SuppressWarnings("null")?


Aggiornamento n. 1

Per quanto riguarda i tipi di caselle non selezionati, secondo questa risposta (sottolineata da @gnat nei commenti seguenti), è necessario sopprimere questi avvisi.

Molte librerie Java indispensabili non sono mai state aggiornate per eliminare la necessità di tipografie non sicure. La soppressione di tali avvisi è necessaria in modo che altri avvisi più importanti vengano rilevati e corretti.

In caso di soppressione di altri avvisi, sempre in una zona grigia.


Aggiornamento n. 2

Secondo Oracle Docs (menzionato anche da alcune risposte di seguito):

Per motivi di stile, i programmatori dovrebbero sempre usare questa annotazione sull'elemento più annidato dove è efficace. Se si desidera sopprimere un avviso in un particolare metodo, è necessario annotare quel metodo anziché la sua classe.



@gnat Non parlano di cast di tipi non controllati‽
Bilesh Ganguly,

1
lo fanno : "Molte librerie Java indispensabili non sono mai state aggiornate per eliminare la necessità di digitare non sicuri. La soppressione di tali avvisi è necessaria affinché altri avvisi più importanti vengano notati e corretti".
moscerino il

2
Penso che il problema con quel duplicato riguardi C #: ci sono alcuni motivi specifici di Java che sono distinti dall'idea generale di sopprimere gli avvisi del compilatore.

Risposte:


26

Per me, il punto fondamentale di sopprimere gli avvisi è mantenere un "buono stato di salute" per il tuo progetto. Se sai che l'intera base di codice viene compilata in modo pulito, è immediatamente ovvio quando qualcuno fa qualcosa di sbagliato che fa apparire il primo avviso nell'elenco dei problemi. È quindi possibile correggere l'errore o eliminarlo se si può dimostrare che è falso.

Ma se hai 21 avvertimenti per cominciare, è molto più probabile che trascuri il 22 ° quando qualcuno lo provoca e non controlli che sia innocuo. Ciò significa che i problemi possono insinuarsi nella tua base di codice e non te ne accorgerai mai.

Gli avvisi sono utili informazioni. Assicurati di ascoltare quelli che dicono la verità e di filtrare quelli che non lo fanno. Non lasciare che le persone mescolino i due tipi in modo da perdere il tuo sistema di allarme rapido.

modificare

Dovrei probabilmente chiarire che sopprimere un avvertimento che ha merito è una cosa sciocca da fare. Un buono stato di salute ottenuto con l'inganno non vale ovviamente nulla. Data la scelta, dovresti sempre risolvere il problema notato dal compilatore anziché limitarti a chiudere gli occhi. Tuttavia, ci sono aree in cui il compilatore non può essere sicuro se qualcosa sarà un problema o meno (i generici di Java sono una di queste aree), e lì la scelta migliore è quella di rivedere ciascuna di queste istanze e quindi sopprimere l'avvertenza in questo luogo specifico piuttosto che disattivare completamente questa classe di avvertimento e potenzialmente perdere una vera e propria.


1
Concordo parzialmente sul fatto che a partire da una lavagna "pulita" ti aiuti a catturare gli avvisi successivi, il fatto è che il codice che viene compilato in modo pulito potrebbe non funzionare in modo pulito.
user949300,

Il problema che ho al lavoro è che spesso incontro avvertimenti che qualcun altro ha soppresso perché non capivano cosa stesse dicendo. Quindi immagino che un avviso abbia un merito sia una questione soggettiva. : /
Trejkaz

16

Sopprimere gli avvisi è qualcosa che deve essere fatto con estrema cura.

Un avvertimento significa: il compilatore ha trovato qualcosa che sembra complicato. Non significa che sia complicato, sembra solo al compilatore. A volte hai un codice che va perfettamente bene e dà un avvertimento. A volte lo aggiusti modificando leggermente il tuo codice. A volte il compilatore ha alcune funzionalità appositamente per quello scopo. Per esempio dove

if (x = someFunction ()) { ... }

dà un avvertimento ma

if ((x = someFunction ())) { ... }

non lo fa. Nel primo caso un avvertimento presuppone che tu abbia eventualmente inteso == e non =. Nel secondo caso nessun avvertimento perché le parentesi extra dicono al compilatore "So cosa sto facendo". Meglio ovviamente lo sarebbe

if ((x = someFunction ()) != 0) { ... }

o usando due righe.

E a volte, molto raramente, ci sono casi in cui il tuo codice va bene ma non riesci a scriverlo in un modo accettato senza preavviso. In quel caso, molto raro, disabiliti un avviso per quell'istruzione e lo attivi immediatamente dopo. Questa è l'ultima risorsa. E disabiliti solo quell'avvertimento specifico, nessun altro.

Tuttavia, alcune persone disabilitano solo gli avvisi per sbarazzarsi degli avvisi, perché sono troppo pigri per scoprire e risolvere prima il motivo di un avviso legittimo. Oppure non provano nemmeno a scrivere codice privo di avvisi. Questa è una cosa estremamente malsana da fare.


2
Penso che potresti perdere alcune parentesi di chiusura nel tuo secondo e terzo esempio.
8bittree,

1
Perfettamente d'accordo con l'ultima frase
usr-local-ΕΨΗΕΛΩΝ

7

Sopprimere l'avvertimento per un intero metodo è sospetto. Meglio sopprimere gli avvisi per la riga specifica, con un commento . per esempio

@SuppressWarnings("unchecked") Foo foo = (Foo)object; // Using old library requires this cast

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.