assert în Java

Excepții Java 1.4

assert verifică o condiție care ar trebui să fie mereu adevărată; aserțiunile sunt dezactivate implicit și se pornesc cu java -ea.

Sintaxă
assert conditie;
assert conditie : "mesaj afișat dacă condiția e falsă";

Ce face assert

assert x >= 0; spune „aici x trebuie să fie pozitiv; dacă nu e, am o greșeală în program”. Când aserțiunile sunt activate și condiția e falsă, se aruncă AssertionError, cu mesajul de după :, dacă există.

Important: aserțiunile sunt dezactivate implicit. Cu java Main, instrucțiunile assert sunt sărite complet (nici condiția nu se evaluează). Se activează cu java -ea Main (-enableassertions), de obicei în dezvoltare și în teste.

De aceea assert nu se folosește pentru validarea datelor de la utilizator sau a parametrilor metodelor publice (pentru asta arunci IllegalArgumentException), ci doar pentru verificări interne. Condiția nu trebuie să aibă efecte secundare, pentru că în producție nu rulează.

Exemple

Exemplul 1: Fără -ea, assert este ignorat

Programul este rulat cu java Main, deci aserțiunea falsă nu oprește nimic. Mai mult, metoda din condiție nu este apelată deloc: contorul rămâne 0. desiredAssertionStatus() arată dacă aserțiunile sunt active pentru clasă.

public class Main {
    static int verificari = 0;

    static boolean pozitiv(int x) {
        verificari++;
        return x > 0;
    }

    public static void main(String[] args) {
        int stoc = -3;
        assert pozitiv(stoc) : "stocul nu poate fi negativ: " + stoc;
        System.out.println("aserțiuni active: " + Main.class.desiredAssertionStatus());
        System.out.println("programul a continuat, stoc = " + stoc);
        System.out.println("verificări făcute: " + verificari);
    }
}

Rezultat

aserțiuni active: false
programul a continuat, stoc = -3
verificări făcute: 0

Exemplul 2: Același program rulat cu java -ea

Cu -ea, condiția falsă aruncă AssertionError cu mesajul dat, iar programul se oprește (cod de ieșire 1).

public class Main {
    static double medie(int[] note) {
        int suma = 0;
        for (int n : note) {
            assert n >= 1 && n <= 10 : "notă invalidă: " + n;
            suma += n;
        }
        return (double) suma / note.length;
    }

    public static void main(String[] args) {
        System.out.println(medie(new int[] {9, 10, 8}));
        System.out.println(medie(new int[] {9, 12}));
    }
}

// $ javac Main.java
// $ java -ea Main

Rezultat (rulat cu java -ea Main)

9.0
Exception in thread "main" java.lang.AssertionError: notă invalidă: 12
	at Main.medie(Main.java:5)
	at Main.main(Main.java:13)

Greșeli frecvente

  • Validezi date de intrare cu assert. În producție aserțiunile sunt oprite și verificarea dispare. Folosește if + throw new IllegalArgumentException(...).
  • Pui cod cu efect în condiție (assert lista.remove(x);). Fără -ea, elementul nu mai e șters, iar programul se comportă diferit.
  • Te aștepți ca testele cu assert să eșueze, dar uiți -ea: totul „trece”. Activează aserțiunile sau folosește un framework de teste (JUnit).

Comenzi înrudite

  • throw și throws: throw aruncă o excepție acum; throws, în antetul metodei, anunță ce excepții verificate poate arunca metoda.
  • try, catch și finally: try încearcă un bloc de cod, catch prinde și tratează excepțiile aruncate în el, iar finally rulează mereu la ieșire.
  • java (lansatorul): java pornește mașina virtuală Java și rulează un program: o clasă compilată, un fișier .jar sau direct un fișier sursă .java.