Ce face throw și throws
throw este o instrucțiune: throw new IllegalArgumentException("mesaj"); oprește imediat metoda și trimite excepția în sus, la apelanți, până când un catch o prinde. Se folosește pentru a refuza date invalide sau pentru a semnala o situație din care metoda nu își poate reveni.
throws stă în antetul metodei și face parte din „contractul” ei: void citeste() throws IOException spune că metoda poate arunca o IOException. Pentru excepțiile verificate (IOException, excepțiile tale care extind Exception) este obligatoriu; pentru cele neverificate (RuntimeException și subclasele) este opțional.
O excepție prinsă poate fi aruncată din nou sau „împachetată” într-una mai potrivită, păstrând cauza: throw new RuntimeException("nu pot încărca", e);. Cauza se citește apoi cu getCause().
Exemple
Exemplul 1: Validare cu throw
setNota aruncă o excepție pentru valori în afara intervalului. Apelantul decide ce face cu ea.
class Catalog {
private double nota;
void setNota(double nota) {
if (nota < 1 || nota > 10) {
throw new IllegalArgumentException("nota trebuie să fie între 1 și 10, nu " + nota);
}
this.nota = nota;
}
double getNota() {
return nota;
}
}
public class Main {
public static void main(String[] args) {
Catalog c = new Catalog();
for (double n : new double[] {9.5, 11, 0, 7}) {
try {
c.setNota(n);
System.out.println("nota salvată: " + c.getNota());
} catch (IllegalArgumentException e) {
System.out.println("respins: " + e.getMessage());
}
}
}
}
Rezultat
nota salvată: 9.5
respins: nota trebuie să fie între 1 și 10, nu 11.0
respins: nota trebuie să fie între 1 și 10, nu 0.0
nota salvată: 7.0
Exemplul 2: throws: excepția urcă prin apeluri
citesteConfig și pornire declară throws IOException, deci nu o tratează; excepția urcă până în main, unde e prinsă. Fișierul nu există în directorul curent.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
public class Main {
static String citesteConfig(String fisier) throws IOException {
System.out.println("citesc " + fisier);
return Files.readString(Path.of(fisier));
}
static void pornire() throws IOException {
String config = citesteConfig("setari.ini");
System.out.println("config: " + config);
}
public static void main(String[] args) {
try {
pornire();
} catch (NoSuchFileException e) {
System.out.println("lipsește fișierul: " + e.getMessage());
} catch (IOException e) {
System.out.println("altă eroare: " + e);
}
}
}
Rezultat
citesc setari.ini
lipsește fișierul: setari.ini
Exemplul 3: Împachetare cu păstrarea cauzei
Eroarea tehnică (NumberFormatException) este transformată într-una pe înțelesul aplicației, iar originalul rămâne accesibil prin getCause().
public class Main {
static int citestePort(String valoare) {
try {
return Integer.parseInt(valoare);
} catch (NumberFormatException e) {
throw new IllegalStateException("configurație greșită: port=" + valoare, e);
}
}
public static void main(String[] args) {
System.out.println("port: " + citestePort("8080"));
try {
citestePort("80a");
} catch (IllegalStateException e) {
System.out.println(e.getMessage());
System.out.println("cauza: " + e.getCause());
}
}
}
Rezultat
port: 8080
configurație greșită: port=80a
cauza: java.lang.NumberFormatException: For input string: "80a"
Greșeli frecvente
- Confunzi cuvintele:
throwsîn corpul metodei sauthrowîn antet nu compilează.throw= acțiune;throws= declarație. - Arunci o excepție verificată fără să o declari:
unreported exception IOException; must be caught or declared to be thrown. - Împachetezi o excepție fără cauză (
new RuntimeException("eroare")în loc denew RuntimeException("eroare", e)) și pierzi informația despre problema reală. - Scrii
throw IllegalArgumentException("x")fărănew:cannot find symbol.
Comenzi înrudite
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.Excepții verificate și neverificate: Excepțiile verificate (Exception) trebuie prinse sau declarate cu throws; cele neverificate (RuntimeException) nu sunt cerute de compilator.try-with-resources: try-with-resources deschide resurse (fișiere, conexiuni) în paranteze și le închide automat la final, chiar dacă apare o excepție.IllegalArgumentException: Excepția aruncată când o metodă primește un argument cu valoare nepermisă (vârstă negativă, lună 13).Exception: Clasa de bază pentru erorile pe care un program le poate trata; getMessage() returnează mesajul dat la creare.