Výjimky
- signalizace chybového stavu
- výjimka je tzv. vyhozena (throw) a pak zachycena (catch)
- výjimka se propaguje do volajících metod, dokud není zachycena
- to může skončit až ukončením celého programu
public class Cisla {
public static void main(String[] args) {
int n = 0;
n = Integer.parseInt("abc");
System.out.printf("n = %d\n", n);
}
}
- v tom případě Java vypíše seznam metod, které výjimku způsobily
(resp. neodchytily)
Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at Cisla.main(Cisla.java:3)
- zachycení výjimky může vypadat takto:
public class CislaZachyt {
public static void main(String[] args) {
int n = 0;
try {
n = Integer.parseInt("abc");
} catch (NumberFormatException e) {
System.out.printf("Nastala vyjimka `%s'.\n", e.getMessage());
}
System.out.printf("n = %d\n", n);
}
}
- všimněte si, že po zpracování tzv. catch-bloku se normálně dále pokračuje
- můžeme ale i výjimku znovu hodit...
public class CislaPrehod {
public static void main(String[] args) {
int n = 0;
try {
n = Integer.parseInt("abc");
} catch (NumberFormatException e) {
System.out.printf("Nastala vyjimka `%s'.\n", e.getMessage());
System.out.println("Hazime dal.");
throw e;
}
System.out.printf("n = %d\n", n);
}
}
- některé výjimky je nutné uvádět už při vytvoření metody
- říkáme tím, že očekáváme, že metoda může skončit neúspěchem
- do hlavičky se pak přidává deklarace
throws
public static void main(String[] args) throws java.io.IOException {
String slovo;
while (true) {
int znak = System.in.read();
if (znak == -1) {
// Konec vstupu.
break;
}
char pismeno = (char) znak;
slovo = slovo + pismeno;
...
}
...
}
- výjimky se často používají na kontrolu, zda je metoda správně volána
public class VyhodVyjimku {
private static int najdiNejmensi(int[] pole) {
if (pole.length == 0) {
throw new IllegalArgumentException("prazdne nema nejmensi prvek");
}
int minIdx = 0;
for (int i = 1; i < pole.length; i++) {
if (pole[i] < pole[minIdx]) {
minIdx = i;
}
}
return pole[minIdx];
}
private static void ukazka(int[] pole) {
System.out.printf("Hledam nejmensi prvek...\n");
int min = najdiNejmensi(pole);
System.out.printf(" ... coz je %d.\n", min);
}
public static void main(String[] args) {
ukazka(new int[] { 2, 4, 6, 1, 8 });
ukazka(new int[] {});
ukazka(new int[] { 3, 5, 2, 7, 9 });
}
}
Čtení ze souborů a zápis do nich
- může být dost komplikované ;-)
- poměrně složitá hierarchie vzájemně propletených tříd a rozhraní
- ale jde pak psát kód, který funguje ať už zapisujeme do souboru
nebo odpovídáme na HTTP žádost nebo tiskneme na obrazovku
- obecný postup
- otevření souboru (reader/writer nebo input/output stream)
- práce se souborem (zápis, čtení)
- zavření souboru (close)
- někdy se až v tomto okamžiku změny odpropagují na disk!
Zápis do souboru (jedna z možností)
import java.io.IOException;
import java.io.PrintWriter;
public class Zapis {
public static void main(String[] args) throws IOException {
PrintWriter writer = new PrintWriter("cisla.txt");
for (int i = 0; i < 10; i++) {
writer.printf("%d ", i);
}
writer.println();
writer.close();
}
}
Čtení ze souboru (také jedna z možností)
- předhodíme skeneru jiný vstup
import java.io.FileReader;
import java.io.IOException;
public class Suma {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("cisla.txt");
int suma = 0;
java.util.Scanner sc = new java.util.Scanner(reader);
while (sc.hasNextInt()) {
suma += sc.nextInt();
}
reader.close();
System.out.printf("Soucet zadanych cisel je %d.\n", suma);
}
}