Ce face Exception.getCause
Când prinzi o excepție de nivel jos și arunci una mai clară pentru cine te apelează, păstrezi excepția originală ca cauză: throw new ServiciuException("nu pot încărca profilul", e). Așa nu se pierde informația despre ce s-a întâmplat de fapt.
getCause() returnează această excepție originală sau null. Cauza poate avea la rândul ei o cauză, deci poți parcurge tot lanțul până la eroarea inițială. Multe clase ale JDK fac asta: ExecutionException și CompletionException învelesc excepția sarcinii, UncheckedIOException învelește o IOException.
Parametri
| Parametru | Descriere |
|---|---|
cauza |
Excepția originală, dată în constructor sau prin initCause. |
Ce returnează
Un Throwable sau null.
Exemple
Exemplul 1: Lanț de excepții parcurs până la capăt
public class Main {
static class ProfilException extends Exception {
private static final long serialVersionUID = 1L;
ProfilException(String mesaj, Throwable cauza) {
super(mesaj, cauza);
}
}
static int varsta(String text) {
try {
return Integer.parseInt(text);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("câmpul vârstă este greșit", e);
}
}
static void incarcaProfil(String varstaText) throws ProfilException {
try {
System.out.println("Vârstă: " + varsta(varstaText));
} catch (IllegalArgumentException e) {
throw new ProfilException("nu pot încărca profilul Anei", e);
}
}
public static void main(String[] args) {
try {
incarcaProfil("2O");
} catch (ProfilException e) {
for (Throwable t = e; t != null; t = t.getCause()) {
System.out.println(t.getClass().getSimpleName() + ": " + t.getMessage());
}
}
}
}
Rezultat
ProfilException: nu pot încărca profilul Anei
IllegalArgumentException: câmpul vârstă este greșit
NumberFormatException: For input string: "2O"
Exemplul 2: Cauza din ExecutionException
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws InterruptedException {
try (ExecutorService executor = Executors.newSingleThreadExecutor()) {
Future<Integer> f = executor.submit(() -> Integer.parseInt("12,5"));
try {
f.get();
} catch (ExecutionException e) {
System.out.println("Excepția prinsă: " + e.getClass().getSimpleName());
System.out.println("Cauza reală: " + e.getCause());
}
}
}
}
Rezultat
Excepția prinsă: ExecutionException
Cauza reală: java.lang.NumberFormatException: For input string: "12,5"
Exemplul 3: Fără cauză: null
public class Main {
public static void main(String[] args) {
Exception simpla = new Exception("eroare simplă");
System.out.println("Cauza: " + simpla.getCause());
Exception cuCauza = new Exception("eroare de sus");
cuCauza.initCause(new ArithmeticException("împărțire la zero"));
System.out.println("Cauza: " + cuCauza.getCause());
}
}
Rezultat
Cauza: null
Cauza: java.lang.ArithmeticException: împărțire la zero
Greșeli frecvente
- Arunci o excepție nouă fără cauză:
throw new RuntimeException("eroare")încatch. Pierzi informația despre eroarea originală; transmiteeca al doilea argument. - Apelezi
getCause().getMessage()fără să verificinull. Nu orice excepție are cauză.
Comenzi înrudite
Exception: Clasa de bază pentru erorile pe care un program le poate trata; getMessage() returnează mesajul dat la creare.RuntimeException: Clasa de bază a excepțiilor neverificate: nu trebuie declarate cu throws și nici prinse obligatoriu.Future: Rezultatul unei sarcini care rulează pe alt fir: get() așteaptă și îl returnează, isDone() spune dacă s-a terminat.CompletableFuture.exceptionally: Tratează o eroare din lanț: dacă un pas anterior a eșuat, funcția primește excepția și returnează o valoare de rezervă.