Domanda Asserire una buona pratica o no?


È una buona pratica usare Assert per i parametri di funzione per far valere la loro validità. Stavo passando attraverso il codice sorgente di Spring Framework e ho notato che usano Assert.notNull Un sacco. Ecco un esempio

   public static ParsedSql parseSqlStatement(String sql) {
    Assert.notNull(sql, "SQL must not be null");}

Ecco un altro:

public NamedParameterJdbcTemplate(DataSource dataSource) {
            Assert.notNull(dataSource,
                    "The [dataSource] argument cannot be null.");
            this .classicJdbcTemplate = new JdbcTemplate(dataSource);
        }

        public NamedParameterJdbcTemplate(JdbcOperations classicJdbcTemplate) {
            Assert.notNull(classicJdbcTemplate,
                    "JdbcTemplate must not be null");
            this .classicJdbcTemplate = classicJdbcTemplate;
      }

Cordiali saluti, The Assert.notNull (non il assert istruzione) è definito in una classe util come segue:

public abstract class Assert { 
   public static void notNull(Object   object, String   message) {
      if (object == null) {
          throw new IllegalArgumentException  (message);
      }
   }
}

44
2018-03-14 02:33


origine


risposte:


In linea di principio, asserzioni non sono così diversi da molti altri controlli di runtime.

Ad esempio, Java bound-controlla tutti gli accessi agli array in fase di esecuzione. Questo rende le cose un po 'più lente? Sì. È utile? Assolutamente! Non appena si verifica una violazione fuori campo, viene generata un'eccezione e il programmatore viene avvisato di eventuali errori! Il comportamento in altri sistemi in cui gli accessi agli array non sono controllati sono MOLTO PIÙ INDIPENDIBILI! (spesso con conseguenze disastrose!).

Le asserzioni, sia che si utilizzi il supporto di una biblioteca o di una lingua, sono simili nello spirito. Ci sono costi di prestazioni, ma ne vale assolutamente la pena. In effetti, le asserzioni sono ancora più preziose perché sono esplicite e comunicano concetti di livello superiore.

Se usato correttamente, il costo delle prestazioni può essere minimizzato e il valore, sia per il cliente (che prenderà le violazioni del contratto prima che dopo) e per gli sviluppatori (perché il contratto è auto-enforcing e auto-documentazione), è massimizzato.

Un altro modo di guardarlo è pensare alle asserzioni come a "commenti attivi". Non si può sostenere che i commenti siano utili, ma sono PASSIVI; computazionalmente non fanno nulla. Formulando alcuni concetti come asserzioni invece di commenti, diventano ATTIVI. In realtà devono rimanere in fase di esecuzione; le violazioni saranno catturate.


Guarda anche: i vantaggi della programmazione con asserzioni


52
2018-03-14 02:47



Questi asseriti sono forniti dalla libreria e non sono gli stessi del built-in assert parola chiave.

C'è una differenza qui: asserts non vengono eseguiti di default (devono essere abilitati con il -ea parametro), mentre le asserzioni fornite dal Assert la classe non può essere disabilitata.

Secondo me (per quello che vale), questo è un buon metodo per la validazione dei parametri. Se avessi usato asserzioni predefinite come suggerisce il titolo della domanda, avrei discusso contro di essa sulla base del fatto che i controlli necessari non dovrebbero essere rimovibili. Ma in questo modo è solo una scorciatoia per:

public static ParsedSql parseSqlStatement(String sql) {
    if (sql == null)
        throw new IllegalArgumentException("SQL must not be null");
    ...
}

... che è sempre una buona pratica da fare nei metodi pubblici.

Lo stile incorporato di asserzioni è più utile per situazioni in cui una condizione dovrebbe sempre essere vera o per metodi privati. Il guida linguistica che introduce asserzioni ha alcune buone linee guida che sono fondamentalmente ciò che ho appena descritto.


25
2018-03-14 02:52



Sì, è una buona pratica.

Nel caso Spring, è particolarmente importante perché i controlli stanno convalidando le impostazioni delle proprietà, ecc. Che in genere provengono da file di cablaggio XML. In altre parole, stanno convalidando la configurazione del webapp. E se mai fai uno sviluppo serio basato su Spring, quei controlli di validazione ti faranno risparmiare ore di debugging quando commetterai uno stupido errore di configurazione.

Ma nota che c'è una GRANDE differenza tra una classe di libreria chiamata Assert e il Java assert parola chiave che viene utilizzata per definire un'asserzione Java. Quest'ultima forma di asserzioni può essere disattivata al momento dell'avvio dell'applicazione e NON deve essere utilizzata per i controlli di convalida degli argomenti che si desidera sempre verificarsi. Chiaramente, i progettisti di Spring pensano che sarebbe una pessima idea disabilitare i controlli di integrità della configurazione webapp ... e sono d'accordo.

AGGIORNARE 

In Java 7 (e versioni successive) il java.util.Objects la classe fornisce a requireNonNull metodo di convenienza per verificare se un argomento è null e sollevare un'eccezione. Lo usi in questo modo:

 SomeType t = ...
 SomeType tChecked = Objects.requireNonNull(t);

o

 SomeType tChecked = Objects.requireNonNull(t, "t should be non-null");

Tuttavia, si noti che questo metodo aumenta NullPointerException piuttosto che IllegalArgumentException.


16
2018-03-14 02:49



Basato su Sun's guida sulle asserzioni, dovresti non usa asserzioni per il controllo degli argomenti nei metodi pubblici.

Il controllo degli argomenti fa generalmente parte delle specifiche (o del contratto) pubblicate di un metodo e queste specifiche devono essere rispettate se le asserzioni sono abilitate o disabilitate.


5
2018-03-14 03:02



In sistemi molto grandi e mal progettati / gestiti, se stai cercando di migliorare la prevedibilità in metodi che sono, ad esempio, 6000 linee e nessuno in azienda li comprende, può essere utile usare la parola chiave assert per creare ambienti di sviluppo far saltare in aria, rivelando bug. Ma se dovessi implementare queste asserzioni in produzione, potresti cortocircuitare una patch che, sebbene orribilmente concepita, ha risolto un problema. Si desidera correggere quella patch errata rilevandola nell'ambiente dev, non in produzione. Quindi, in fase di sviluppo, attiveresti e li disattiverai in produzione.

Un altro uso valido della parola chiave assert al momento dello sviluppo consiste nell'inserire i controlli di validità in algoritmi che devono essere eseguiti in tempi inferiori al millisecondo e che sono sufficientemente isolati dai chiamanti imprevedibili o non testati. Potrebbe non essere possibile permettersi di conservare il controllo di validità in produzione in questo caso, sebbene sia ancora molto utile in fase di sviluppo. D'altra parte, se l'origine dei parametri che stai convalidando è imprevedibile o potrebbe diventare tale (se è determinata in parte dall'input dell'utente, ad esempio), probabilmente non puoi mai permettersi di saltare il controllo, anche in produzione, e dovrebbe prendere il colpo di prestazione come un costo di fare affari. (In quest'ultimo caso, probabilmente non si vorrebbe usare un assert.) Ma si dovrebbe optare per gli asserzioni per eliminare un controllo di validità in fase di produzione solo dopo la profilazione ti dice che semplicemente non puoi permetterti il ​​sovraccarico.


2
2017-11-06 19:07



Sì, è una buona idea. Stai rafforzando il contratto dell'interfaccia o della classe. Se c'è una violazione del contratto, la vuoi rilevare il prima possibile. Più a lungo si attende, più i risultati possono essere imprevedibili e più difficile può essere diagnosticare.

Quando controlli esplicitamente in questo modo, dovresti anche fornire un messaggio informativo che, se visualizzato in un file di registro, può fornire un contesto utile per aiutarti a trovare la causa principale o anche solo per capire che hai assunto un'ipotesi sbagliata su quale sia il contratto.


1
2018-03-14 02:38



Sto mantenendo il mio asserzioni nei binari rilasciati ma con un comportamento modificato: l'abort non viene chiamato ma lo stacktrace viene raccolto.

Maggiori dettagli qui: http://blog.aplikacja.info/2011/10/assert-to-abort-or-not-to-abort-thats-the-question/


0
2017-09-18 21:20