Perché è assert non abilitato di default in java

La mia domanda è dal punto di vista del design del linguaggio.

Perché viene asserito in modo diverso, ovvero genera un errore e non un’eccezione, non è abilitato di default ecc.

Sembra elegante (opinione molto soggettiva), facile da leggere (di nuovo soggettiva) per fare validazioni e ci sono anche strumenti (IDE) che possono essere valutati in tempo reale e fornire avvertimenti basati su asserzioni.

Direi che la ragione è che le impostazioni predefinite per Java sono pensate per creare una versione “di rilascio” del software – se gli utenti hanno bisogno di build il tuo codice useranno i default forniti e se sei uno sviluppatore e vuoi avere un report migliore puoi sempre fare qualche sforzo aggiuntivo.

Di solito non vuoi spedire asserzioni con una versione di rilascio. Perché? È sempre ansible progettare il codice per eseguire alcuni errori di background che non gestiscono l’errore e l’esecuzione di AssertionError negli utenti non è sempre la strada da percorrere.

Il più delle volte li vedo usati come test di codice aggiuntivo: quando si eseguono test di regressione e la copertura del codice è elevata, nessun errore di asserzione suggerisce che non ci siano errori (ovvi da individuare) nel codice. Se alcuni capita, puoi dedurre dallo stack trace cosa è andato storto e perché. D’altra parte i clienti non dovrebbero essere disturbati nel vedere le informazioni descrittive sugli errori.

Quindi come dovresti effettivamente usarli? Nella mia esperienza, dovresti progettare il codice per non utilizzare le asserzioni per eseguire la gestione degli errori. Se vuoi che venga lanciata un’eccezione, gettala esplicitamente da te. Una volta che il codice è in grado di gestire se stesso, è ansible aggiungere asserzioni per controllare pre e postcondizioni e invarianti, quindi in pratica li utilizza per verificare la correttezza dell’algoritmo anziché la correttezza dei dati. Ha un valore per gli sviluppatori piuttosto che per gli utenti. Una volta che hai abbastanza fiducia nella tua soluzione, puoi disabilitare le asserzioni, il tuo programma funziona ancora bene e gli utenti non devono eseguire programmi con sovraccarico di runtime aggiuntivo.

Le asserzioni sono strumenti per lo sviluppatore.

Il motivo principale per cui non è abilitato per impostazione predefinita è che le asserzioni tramite assert non sono intese a fornire la convalida / protezione in fase di esecuzione per il codice di produzione.

assert è uno strumento da utilizzare nel processo di sviluppo e durante i test che non dovrebbe influire sulle prestazioni durante l’effettivo funzionamento nell’ambiente di produzione.

Immagina un peso molto pesante che è fondamentale per verificare quando si costruisce una nuova funzionalità o una modifica rispetto a un’intera gamma di input consentiti, ma una volta costruito e testato correttamente, non è necessario eseguire le modifiche al codice.

Solleva un errore, perché la gravità di una violazione di asserzione è abbastanza alta per farlo.

Un esempio per ArrayIndexOutOfBounds è qualcosa come ArrayIndexOutOfBounds . Ciò potrebbe essere ragionevole in alcuni casi e potresti persino aspettarti (e gestire) un caso del genere.

Ma una violazione di asserzione è (ad esempio, per memoria esaurita) nulla che ti aspetteresti o ti piacerebbe affrontare. È un errore e non ci sono scuse.

Le asserzioni non sono abilitate di default, perché dovrebbero essere sempre riempite. Puoi metterli alla prova per questo, ma poi “sai” (per quanto ne sai tu) che non sono violati. Quindi non è necessario controllare le condizioni (che potrebbero richiedere prestazioni elevate) ogni volta nel codice di produzione.

La cosa buona delle asserzioni in Java è che il codice che esegue effettivamente i controlli non viene mai eseguito, quando le asserzioni non sono abilitate.

Per esempio:

 if (!doComplexChecks()) throw new AssertionError("Damn!"); 

potrebbe richiedere molto tempo e si desidera verificarlo quando si esegue il test o il debug delle unità, ma in produzione non lo si desidera.

Ma questo codice

 assert doComplexChecks(); 

viene eseguito solo quando le asserzioni sono abilitate, quindi ti fa risparmiare un sacco di tempo nel codice di produzione.