Obsah 7. přednášky: Tato tematika je zpracována v Záznamy přednášek: str

Podobné dokumenty
Z. Kotala, P. Toman: Java ( Obsah )

Semin aˇr Java V yjimky Radek Ko ˇc ı Fakulta informaˇcn ıch technologi ı VUT Unor 2008 Radek Koˇc ı Semin aˇr Java V yjimky 1/ 25

Výjimky. A0B36PR2-Programování 2 Fakulta elektrotechnická České vysoké učení technické

Algoritmizace a programování

1. Téma 12 - Textové soubory a výjimky

8. přednáška: Soubory a proudy

Soubor jako posloupnost bytů

Algoritmizace a programování

Úvod do programování - Java. Cvičení č.4

KTE / ZPE Informační technologie

Java - výjimky. private void vstup() throws IOException {... }

Práce se soubory v Javě

Programové konvence, dokumentace a ladění. Programování II 2. přednáška Alena Buchalcevová

Tato tematika je zpracována v Záznamy přednášek: str

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

Výjimky. v C# a Javě

Úvod do programovacích jazyků (Java)

6. Příkazy a řídící struktury v Javě

Výjimky. Tomáš Pitner, upravil Marek Šabo

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

17. Projekt Trojúhelníky

ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů

KTE / ZPE Informační technologie

Úvod do programovacích jazyků (Java)

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Regulární výrazy. Vzory

Typický prvek kolekce pro české řazení

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Řídicí struktury. alg3 1

Java a XML. 10/26/09 1/7 Java a XML

Obsah přednášky. Příkaz for neúplný. Příkaz for příklady. Cyklus for each (enhanced for loop) Příkaz for příklady

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

7. Datové typy v Javě

Ošetřování chyb v programech

29. Výjimky, jejich vznik, vyhození, odchyt a zpracování. (A7B36PVJ)

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

6. PRÁCE S DATOVÝMI PROUDY

Abstraktní datové typy: zásobník

Algoritmizace, základy programování, VY_32_INOVACE_PRG_ALGO_01

Algoritmizace. Cíle předmětu

Datové struktury. alg12 1

Algoritmizace řazení Bubble Sort

8 Třídy, objekty, metody, předávání argumentů metod

Algoritmizace a programování. Terminálový vstup a výstup

Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost rozhraním a výjimkám.

Statické proměnné a metody. Tomáš Pitner, upravil Marek Šabo

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Zápis programu v jazyce C#

Textové soubory. alg9 1

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Vytváření a použití knihoven tříd

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Počítačové laboratoře bez tajemství aneb naučme se učit algoritmizaci a programování s využitím robotů CZ.1.07/1.3.12/

1. Programování proti rozhraní

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

Java Výjimky Java, zimní semestr

Projekty pro výuku programování v jazyce Java

Tato tematika je zpracována v Záznamy přednášek: str

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Pole a kolekce. v C#, Javě a C++

Řídicí příkazy KAPITOLA 3. Vstup znaků z klávesnice

Tato tematika je zpracována v Záznamy přednášek: str Problém: Proveďte jednoduchou analýzu zadaného textu (četnost výskytu písmen).

Programování v Javě I. Leden 2008

Teoretické minimum z PJV

Programování v C++, 2. cvičení

Pokud zadání nerozumíte nebo se vám zdá nejednoznačné, zeptejte se. Pište čitelně, nečitelná řešení nebudeme uznávat.

OOPR_05. Případové studie

Dědičnost (inheritance)

součet cvičení celkem. známka. Úloha č.: max. bodů: skut. bodů:

Příkaz while. while (podmínka) { příkaz; } Příklad: int i=0; while (i < 10) { System.out.println(i); i++; } // vypíše čísla od 0 do 9

5 Rekurze a zásobník. Rekurzivní volání metody

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

Programování v Javě I. Únor 2009

Obsah. Úvod 11 Základy programování 11 Objektový přístup 11 Procvičování 11 Zvláštní odstavce 12 Zpětná vazba od čtenářů 12 Errata 13

Výčtový typ strana 67

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Paměť počítače. alg2 1

Class loader. každá třída (java.lang.class) obsahuje referenci na svůj class loader. Implementace class loaderu

InputStream. FilterInputStream

RMI Remote Method Invocation

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

5. přednáška - Rozklad problému na podproblémy

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

10. března 2015, Brno Připravil: David Procházka. Programovací jazyk C++

Generické programování

Práce s textem. Třída Character. Třída Character. Třída Character. reprezentuje objekty zapouzdřující hodnotu typu char (boxing / unboxing)

Seznamy a iterátory. Kolekce obecně. Rozhraní kolekce. Procházení kolekcí

Programovací jazyk Java

Algoritmy a datové struktury

Algoritmizace a programování

Semestrální práce 2 znakový strom

Úvod do programovacích jazyků (Java)

9. přednáška - třídy, objekty

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Tato tematika je zpracována v Záznamy přednášek: str Problém: Proveďte jednoduchou analýzu zadaného textu (četnost výskytu písmen).

Transkript:

Obsah 7. přednášky: Soubory - terminologie Adresáře a soubory - třída File Výjimky - úvod Druhy výjimek Způsoby reakce na výjimku Kompletní ošetření výjimky Nejhorší reakce na výjimku Seskupování a selekce výjimek Výjimky pro pokročilé* Ladění programů Tato tematika je zpracována v Záznamy přednášek: str. 153 166 Přednášky KIV/PPA1, A. Netrvalová, 2016 7. přednáška

Soubory - terminologie Soubor - množina údajů uložená na vnější paměti počítače, obvykle na disku Soubor (pro začátečníky) - základní struktura pro ukládání dat na vnější paměťové médium - složen z jednotlivých záznamů, které se skládají z položek - soubory s pevnou délkou nebo soubory s proměnnou délkou - data v souborech se zpracovávají pouze v operační paměti. Přesouvání dat z vnější do operační paměti se provádí použitím vyrovnávací paměti, tj. tzv. bufferem - jednotkou přenosu dat je tzv. logický blok (cluster, page, stránka). - základní ideou při fyzické implementaci souborů je minimalizace přístupů na disk při zpracování dat. Přístupy na disk nejvíce zpomalují proces zpracování dat. - nejčastěji se používají soubory sekvenční, indexsekvenční, indexové a s přímým přístupem Jen pro informaci: Kromě primárního souboru, tj. souboru obsahujícího všechna data, může soubor obsahovat i přídavnou datovou strukturu, spojenou vždy s vybranou položkou (položkami) primárního souboru. Tato položka (atribut) se nazývá vyhledávací klíč a datovou strukturou je index. Strana 2 (celkem 31)

Typy souborů přístup k datům v souboru - sekvenční - index-sekvenční - indexové soubory - soubory s přímým přístupem Sekvenční soubor je kolekce záznamů, obvykle pevné délky, umístěných postupně za sebou (tj. v předem určeném pořadí) ve vymezeném prostoru na vnějším paměťovém médiu. My budeme dále pracovat pouze se sekvenčními soubory. Jen pro informaci: Index-sekvenční soubor je tvořen tzv. primárním souborem, tj. seřazeným sekvenčním souborem (dle primárního klíče) a přídavnou datovou strukturou - index. Indexový soubor je tvořen primárním souborem a indexy pro různé vyhledávací klíče, ale indexovány jsou záznamy, proto nemusí být primární soubor seřazen (na rozdíl od index-sekvenčního souboru) a nevyžaduje umístění do souvislé části paměti. Soubor s přímým přístupem umožňuje rychlý způsob vyhledávání záznamů podle hodnoty primárního klíče i jeho aktualizaci. Při ukládání záznamu do souboru se z hodnoty primárního klíče vypočte adresa bloku (stránky) disku, na níž má být daný výskyt záznamu uložen. Hodnota primárního klíče je vstupem a adresa stránky je výstupem tzv. hashovacích algoritmů (viz PPA2 a PT). Strana 3 (celkem 31)

Terminologie sjednocení pojmů Přípona vše za poslední tečkou:.java,.txt Jméno souboru Kruh.java, data.txt (někdy jen část před tečkou, např. spouštění programu v Javě z příkazové řádky: java Kruh) Aktuální adresář - značení. Nadřazený adresář (rodičovský) - značení.. Podadresář (vnořený) Kořenový adresář značení Win \, Linux / Úplná cesta adresářová cesta z kořenového do aktuálního adresáře, např. D:\vyuka\ppa1\programy Úplné jméno souboru úplná cesta + jméno souboru, např. D:\vyuka\ppa1\programy\Kruh.java Relativní cesta (neúplná), relativní jméno souboru - cesta z nějakého adresáře (např. aktuálního) k souboru (raději moc neužívat častá chyba), např... \ppa1\programy\kruh.java Poznámka pozor na odlišnosti oddělování adresářů a souborů v různých operačních systémech (\, /) Typické operace se souborem - otevření, zápis, čtení, uzavření Strana 4 (celkem 31)

Adresáře a soubory - třída File Poznámka zde soubor chápán jako celek bez uvažování o obsahu Práce se soubory třída File - souborový manažer, který nezajišťuje způsob čtení, zápisu, používá se i pro adresáře (rozlišuje se pomocí metod isdirectory(), isfile()) - zajišťuje např. test existence, vytváření, mazání, přejmenování, přesun, zisk informací o souboru - balík java.io (import java.io.*.;) Vytvoření instance File - soubor nemusí existovat! JVM Program a.txt? a.txt Poznámka Vytvoření instance využívající jméno souboru nebo adresáře neznamená, že uvedený soubor nebo adresář existuje fyzicky na disku. Existovat může, ale také nemusí. Způsoby vytvoření instance - konstruktory: - jméno souboru v aktuálním adresáři - objekt podadresáře a souboru v podadresáři - jméno podadresáře v aktuálním adresáři a jméno souboru v tomto podadresáři Strana 5 (celkem 31)

File soubora = new File("sA.txt"); System.out.println(souborA.getCanonicalPath()); D:\vyuka\ppa1\soubory\sA.txt File actualadr = new File("."); System.out.println(actualAdr.getCanonicalPath()); File souborb = new File(actualAdr,"sB.txt"); System.out.println(souborB.getCanonicalPath()); D:\vyuka\ppa1\soubory D:\vyuka\ppa1\soubory\sB.txt File souborc = new File("adresar", "sc.txt"); System.out.println(souborC.getCanonicalPath()); D:\vyuka\ppa1\soubory\adresar\sC.txt Poznámka: Ani jeden z předchozích souborů a ani adresář adresar neexistoval. Práce s existujícím souborem či adresářem Metody pro zisk informací o souboru: boolean exists() - testuje existenci souboru boolean isfile() - testuje, je-li to soubor boolean isdirectory() - testuje, je-li to adresář long length() - velikost souboru (počet bytů) long lastmodified() - čas poslední úpravy (počet ms od 1.1.1970), pro výpis data je nutno použít viz následující příklad: Strana 6 (celkem 31)

File soubor = new File("s.txt"); System.out.println(soubor.getCanonicalPath()); Calendar c = new GregorianCalendar(); c.settimeinmillis(soubor.lastmodified()); System.out.format("%tF%n",c); // pokud soubor s.txt existuje // pokud soubor s.txt neexistuje Metody pro změny: delete() vymazání souboru renameto(file x) přejmenování, přesun souboru import java.io.file; public class Vymazani { 2010-08-14 1970-01-01 public static void main(string[] a) throws IOException { String jmeno = "src\\p07priklady\\tridafile\\smazani\\data.txt"; File f = new File(jmeno); // zde jiz existuje System.out.println(f.getName()+ " " + f.exists()); if(f.exists()) f.delete(); // pokud byl jiz vytvoren, smaze ho System.out.println(f.getName()+ " " + f.exists()); f.createnewfile(); /* vytvori prazdny soubor, jen pokud soubor daneho jmena jiz neexistuje */ System.out.println(f.getName()+ " " + f.exists()); f.delete(); // zakomentovat dalsi smazani souboru System.out.println(f.getName()+ " " + f.exists()); data.txt true data.txt false data.txt true data.txt false Strana 7 (celkem 31)

File soubora = new File("sA.txt"); System.out.println(souborA.getName()+ " " + soubora.exists()); File souborb = new File("sB.txt"); soubora.renameto(souborb); System.out.println(souborB.getCanonicalPath()); System.out.println(souborA.getName()+ " " + soubora.exists()); sa.txt true D:\vyuka\ppa1\soubory\sB.txt sa.txt false Metody pro vytvoření adresáře: mkdirs() - vytvoří 1 nebo skupinu adresářů File adr =new File("nadrazeny" + File.separator + "vnoreny"); System.out.println(adr.getCanonicalPath()+ " " + adr.exists()); adr.mkdirs(); System.out.println(adr.getCanonicalPath()+ " " + adr.exists()); D:\vyuka\ppa1\soubory\ nadrazeny\vnoreny false D:\vyuka\ppa1\soubory\ nadrazeny\vnoreny true Metody pro výpis položek adresáře: String [] list() - jména souborů a podadresářů File [] listfiles() - soubory a podadresáře (objektyfile) import java.io.*; import java.util.*; public class VypisAdr { public static void main (String[] args) throws Exception { File adr =new File(".."); String []jmena = adr.list(); System.out.println(Arrays.toString(jmena)); // napriklad: [info, uvod, vypis, vytvoreni, zmeny] Strana 8 (celkem 31)

Výjimky úvod jen základ více v dalších předmětech (OOP, PT) - pojem výjimka (exception) označení nežádoucí události, jejíž vznik chceme odstranit - mechanismus výjimek velmi silný bezpečnostní prvek - na úrovni kompilátoru nutí programátora k reakci na možné chybové stavy - vyhození výjimky (throws exception) - reakce na výjimku - propagace, deklarace - ošetření (konstrukce try-catch) - kombinace obou způsobů Druhy výjimek z pohledu programátora - Exception (checked exception) nutné ošetření např. u metod V/V - RunTimeException - dobrovolné ošetření např. dělení nulou, index mimo rozsah pole ClassNotFoundException Exception IOException AWTException RuntimeException... další třídy ArithmeticException NullPointerException IndexOutOfBoundsException... další třídy Strana 9 (celkem 31)

1. Příklad: čtení ze souboru Exception (povinné ošetření neprovedeno) import java.util.*; import java.io.*; public class IlustraceVyjimky { private static Scanner sc; public static int [] nactipole(){ sc = new Scanner(new File("pole.txt")); int pocetprvku = sc.nextint(); int [] pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); return pole; public static void main(string[]args){ System.out.print(Arrays.toString(nactiPole())); IlustraceVyjimky.java:7: unreported exception java.io.filenotfoundexception; must be caught or declared to be thrown Scanner sc = new Scanner(new File("pole.txt")); ^ 1 error Poznámka Vstupní soubor totiž nemusí existovat, či může mít jiné jméno. Potřebná úprava bude uvedena v další části. Strana 10 (celkem 31)

2. Příklad: nastavení indexu mimo rozsah pole RunTimeException (neošetřená výjimka) public class IlustraceVyjimkyNeosetrene { public static void main(string[]args){ int [] pole = new int [5]; System.out.println(pole[5]); >"C:\Program Files\Java\jdk1.6.0_02\bin\java" IlustraceVyjimkyNeosetrene Exception in thread "main" java.lang.arrayindexoutofboundsexception: 5 at IlustraceVyjimkyNeosetrene.main(IlustraceVyjimkyNeosetre ne.java:5) >Exit code: 1 Způsoby reakce na výjimku - propagace, deklarace (předání nadřazené úrovni) - ošetření (zachycení a ošetření v místě výskytu) - ošetření v místě výskytu a předání informace nadřazené úrovni Propagace - neboli šíření výjimek metoda, v níž se výjimka vyskytla, se zříká odpovědnosti za zpracování, což provede deklarací v hlavičce metody - throws (vyhazuje) Strana 11 (celkem 31)

throws Exception - znamená pouhé odsunutí problému ošetření musí být někdy a někde (např. v main()) provedeno Příklad import java.util.*; import java.io.*; public class IlustraceVyjimky { private static Scanner sc; public static int [] nactipole() throws Exception { sc = new Scanner(new File("pole.txt")); int pocetprvku = sc.nextint(); int [] pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); return pole; public static void main(string[]args) { System.out.print(Arrays.toString(nactiPole())); IlustraceVyjimkyPovinneOsetreni.java:17: unreported IlustraceVyjimkyPovinneOsetreni.java:17: exception java.lang.exception; must be caught or declared to be thrown System.out.print(Arrays.toString(nactiPole())); 1 error unreported exception java.lang.exception; must be caught or declared to be thrown System.out.print(Arrays.toString(nactiPole())); ^ ^ 1 error Chybové hlášení po překladu je způsobeno odsunutím řešení problému do metody main(). Náprava - v hlavičce metody main() provedeme stejnou úpravu throws Exception Strana 12 (celkem 31)

import java.util.*; import java.io.*; public class IlustraceVyjimky { private static Scanner sc; public static int [] nactipole() throws Exception { sc = new Scanner(new File("pole.txt")); int pocetprvku = sc.nextint(); int [] pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); return pole; public static void main(string[]args) throws Exception { System.out.print(Arrays.toString(nactiPole())); Exception in thread "main" java.io.filenotfoundexception: pole.txt (Systém nemůže nalézt uvedený soubor) at java.io.fileinputstream.open(native Method) at java.io.fileinputstream.<init>(fileinputstream.ja va:106) at java.util.scanner.<init>(scanner.java:636) at IlustraceVyjimkyPovinneOsetreni.nactiPole(Ilustra cevyjimkypovinneosetreni.java:7) at IlustraceVyjimkyPovinneOsetreni.main(IlustraceVyj imkypovinneosetreni.java:17) Chybové hlášení je způsobeno faktem, že soubor neexistuje (není ve společném adresáři). Pokud jej vytvoříme a naplníme správnými daty, vše funguje. Strana 13 (celkem 31)

Výhody jednoduchost, minimum práce Nevýhody nutno při každém použití metody řešit vzniklé problémy. Pro volání často a z různých míst naprosto nevhodné! Kompletní ošetření výjimky - řešena přímo v metodě, neproniká ven - konstrukce try-catch blok try - výkonný kód blok catch - druh výjimky a způsob reakce (výpis chyby a ukončení, nebo i řešení) Příklad 1a: jen výpis a ukončení (rozumná reakce) import java.util.*; import java.io.*; public class IlustraceVyjimkyOsetreniVypisem { private static Scanner sc; public static int[]nactipole() throws Exception { int pole [] = null; // vysunuti deklarace try { sc = new Scanner(new File("pole.txt")); int pocetprvku = sc.nextint(); pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); return pole; catch (Exception e) { e.printstacktrace(); // chybovy vypis (použijeme v SP) System.exit(1); // ukonceni return pole; Strana 14 (celkem 31)

// pokracovani z predchozi stranky public static void main(string[]args) throws Exception { System.out.println(Arrays.toString(nactiPole())); Poznámka: Samotný výpis výjimky program neukončí, nutno provést ukončení příkazem: System.exit(1); Chybový výpis, pokud soubor neexistuje: java.io.filenotfoundexception: pole.txt (Systém nemůže nalézt uvedený soubor) at java.io.fileinputstream.open(native Method) at java.io.fileinputstream.<init>(fileinputstre am.java:106) at java.util.scanner.<init>(scanner.java:636) at IlustraceVyjimkyOsetreniVypisem.nactiPole(Il ustracevyjimkyosetrenivypisem.java:10) at IlustraceVyjimkyOsetreniVypisem.main(Ilustra cevyjimkyosetrenivypisem.java:26) Strana 15 (celkem 31)

Příklad 1b: RunTimeException (rozumná reakce) nastavení indexu mimo rozsah pole ošetření výpisem a ukončení (neošetřená výjimka - viz Druhy výjimek Příklad 2) public class IlustraceVyjimkyOsetrene { static int vratprvekpole(int [] pole, int index) { try { return pole[index]; // vraceni indexu catch (ArrayIndexOutOfBoundsException e) { System.out.println("Zachycena vyjimka: index = " + e.getmessage()); return -index; // vraceni zaporneho indexu public static void main(string[] args) { int xxx [] = new int[10]; for(int i=0; i<xxx.length; i++){ xxx[i] =i; for(int i=1; ;i+=xxx.length) { int ind = vratprvekpole(xxx, i); if(ind < 0){ // a jeho vyuziti System.out.println("Program ukoncen."); System.exit(1); else { System.out.println("index = " + ind); index = 1 Zachycena vyjimka: index = 11 Program ukoncen. // lepe: spojit s: assert (viz str. 25) Strana 16 (celkem 31)

Příklad 2: lepší řešení je (pokud to lze) pokusit se o nápravu vzniklého problému Např. - pokud je chybně zadán název souboru, umožnit jeho opětovné zadání import java.util.*; import java.io.*; public class IlustraceVyjimkyKompletniOsetreni { public static int [] nactipole(){ int pole [] = null; String nazevsouboru = "xxx.txt"; // spravne: pole.txt while (true){ try{ Scanner sc = new Scanner(new File(nazevSouboru)); int pocetprvku = sc.nextint(); pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); break; catch (Exception e) { System.out.println("Soubor " + nazevsouboru + " nenalezen."); System.out.print("Zadej spravne jmeno: "); Scanner klavesnice = new Scanner (System.in); nazevsouboru = klavesnice.next(); Soubor xxx.txt nenalezen. return pole; Zadej spravne jmeno: pole Soubor pole nenalezen. /* Pozor na umisteni souboru a Zadej spravne jmeno: pole.txt pripadne zadani cesty k nemu. [1, 2, 3, 4, 5] */ Strana 17 (celkem 31)

Nejhorší reakce na výjimku - na první pohled nejjednodušší řešení, ale...! - většinou zapomenutí či lenost programátora import java.util.*; import java.io.*; public class IlustraceVyjimkyOsetreniNevhodne { private static Scanner; public static int []nactipole() { int pole [] = null; try{ sc = new Scanner(new File("pole.txt")); int pocetprvku = sc.nextint(); pole = new int [pocetprvku]; for(int i=0; i<pole.length; i++){ pole[i] = sc.nextint(); return pole; catch (Exception e) { // NIC!!! // takto rozhodne ne! return pole; public static void main(string[]args) { System.out.println(Arrays.toString(nactiPole())); Pokud soubor neexistuje - vypis null Takto ztratíme veškeré výhody výjimek, výjimka proběhne, ale nedozvíme se kdy a kde! Strana 18 (celkem 31)

Seskupování a selekce výjimek - např. dvě výjimky a chceme reagovat na obě. - to lze, neboť není omezen počet catch bloků Seskupování výjimek try {... catch(numberformatexception e){ System.out.println("Cislo " + e.getmessage() + " :spatne zadano "); catch(ioexception e){ System.out.println("Chyba pri cteni"); Postupná selekce výjimek try {... catch(numberformatexception e){ /* zpracuje se pouze jedna vyjimka ze tridy RuntimeException */ catch(runtimeexception e){ /* zpracuji se vsechny ostatní vyjimky ze tridy RuntimeException */ Strana 19 (celkem 31)

Výjimky - pouze pro pokročilé* někdy je třeba na zachycenou výjimku nereagovat, pak je nutno napsat do bloku catch komentář proč. Další možnost: převedení Exception na RunTimeException (používá se při zavírání souborů) Konstrukce try-catch-finally konstrukce try-catch se často doplňuje dalším blokem finally, ten probíhá vždy - bez ohledu, zda nastane výjimka (catch) nebo nenastane (try) (používá se při práci se soubory uzavření souborů) try { // vykonny kod, // provede se cely, nevznikne-li vyjimka catch (Exception e) { // kod zachyceni vyjimky // provadi se po vyskytu vyjimky finally { // ukoncovaci kod // provadi se vzdy jako posledni... více v P. Herout: Učebnice jazyka Java (str. 257-260) Poznámka: od Java verze 1.7 příkaz try-with-resources - viz http://docs.oracle.com/javase/7/docs/technotes/guides/langure/t ry-wit-resources.html a catching-multiple-exception-types catchmultiple.html Strana 20 (celkem 31)

static String readfirstlinefromfilewithfinallyblock(string path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readline(); finally { if (br!= null) br.close(); //---------------------- od verze Java 1.7 ------------------------------------ static String readfirstlinefromfile(string path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readline(); catch (IOException ex) { logger.log(ex); throw ex; catch (SQLException ex) { logger.log(ex); throw ex; //---------------------- od verze Java 1.7 ------------------------------------ catch (IOException SQLException ex) { logger.log(ex); throw ex; Poznámka ukázka (spustit) motivační příklad pro další přednášku (použití textových souborů) Strana 21 (celkem 31)

Ladění programů, příkaz Assert Jak přehledně zapisovat kód? - vhodná volba názvů identifikátorů - odsazení pomocí Tab - vkládaní mezer a volných řádek - neopakování sekvencí kódu Typy chyb Syntaktické ( pravopisné chyby) - porušení syntaxe daného jazyka, projeví chybou při kompilaci Logické, chyby v logickém návrhu programu, nejhůře se hledají (program běží, nevypisuje žádné chybové hlášení, ale nepracuje správně) Run time - vznikají až při běhu programu (různé příčiny) Ladění programu shora/zdola: Shora: ladíme nejprve kostru, zatím chybějící metody nahradíme provizorními, které dávají nějaký triviální výstup (zvolenou hodnotu) v požadovaném tvaru Zdola: ladíme nejprve dílčí metody, pro otestování správné funkce metod si vytváříme pomocné testovací programy, které metody volají se zvolenými parametry a vypisují (případně i testují) jejich výstupy Odstraňování chyb Postupné zakomentování jednotlivých částí kódu Průběžné výpisy proměnných Debugger - hledávání chyb (body přerušení, krokování kódu, sledování hodnot proměnných, ) Automatické testování - zabraňuje návratu opravených chyb, snižuje výskyt chyb v budoucnu Strana 22 (celkem 31)

Jakým způsobem testovat programy? - žádný nástroj za nás nevymyslí, JAK máme své programy testovat - data - vhodná volba testovacích dat, náhodná data - testovat okrajové a extrémní hodnoty - program - otestovat všechny větve - otestovat podmínky, konečnost cyklů - ověřování podmínek za běhu - assert Assert (bez kontroly obvyklé spuštění, pro kontrolu spustit: java ea Jmeno) Příklad 1 ilustrace použití dat (známe výsledek!) Spočtěte 5 cislo, log10 hodnota Řešení: cislo = 32, hodnota = 10 Příklad 2 (ilustrace použití Assert) Pro zadané číslo c má platit podmínka: 0 c 10 import java.util.scanner; /** použijte -ea v příkazu java */ public class Assert { private static Scanner sc = new Scanner(System.in); public static void main( String args[] ) { System.out.print("Zadejte cislo mezi 0 and 10: "); int cislo = sc.nextint(); // pozadavek: cislo musi byt >= 0 a <= 10 assert (cislo >= 0 && cislo <= 10) : "Chybne cislo: " + cislo; System.out.printf( "Zadali jste %d\n", cislo ); Strana 23 (celkem 31)

Obdobně: ochrana před použitím indexu mimo rozsah pole: assert (index >= 0 && index < a.length): "\nchyba: index = " + index + " je mimo meze: [0.." + a.length + "]"; import java.util.*; public class AssertPoleIlustracni { // pouzijte -ea v prikazu java private static Random r = new Random(); public static void main( String args[] ) { int[] a = new int[r.nextint(10) + 1]; // náhodná int index = a.length+1; // index = 0 ; // tento index bude vždy ok! for(int i=0; i<a.length; i++){ a[i] = r.nextint(10); System.out.println("Pole: " + Arrays.toString(a)); System.out.println("Meze pole: [0.." + a.length + "]"); // tvrdime, ze index musi byt >= 0 a < delka pole a assert(index >= 0 && index < a.length): "\nchyba: index = " + index + " mimo meze: [0.." + a.length + "]"; System.out.printf("Zvolen index %d, ", index); System.out.println("a[" + index + "] = " + a[index]); // jeste vylepsime pouzitim vyjimek Strana 24 (celkem 31)

Při zpracování výjimky v bloku catch možno použít příkaz assert. Příklad: ještě jednou - ošetření mezí pole public class AssertArrayBoundsExample { private static Scanner sc = new Scanner( System.in ); public static void osetrenimezipole(int [] pole, int index) { try { int x = pole[index]; catch (Exception e){ assert (index >= 0): "\nchyba - index mimo dolni mez! Index = " + index + ", ale mez = " + "0."; assert (index <= pole.length-1) : "\nchyba - index mimo horni mez! Index = " + index + ", ale mez = " + (pole.length-1) + "."; e.printstacktrace(); System.out.println("Detailni popis chyby - spustte s: -ea"); System.exit(1); Strana 25 (celkem 31)

public static void main( String args[] ) { // vytvoreni pole dane velikosti System.out.print( "Zadejte velikost pole: " ); int velikostpole = sc.nextint(); int pole [] = new int [velikostpole]; // naplneni pole for(int i=0; i<pole.length; i++) { pole[i]=i+1; // osetrime rozsah pole: musi byt >= 0 a < pole.length int j=0; while(true){ System.out.print("Vypiste prvek na indexu: "); j = sc.nextint(); osetrenimezipole(pole, j); System.out.format("Zadali jste index %d, hodnota prvku je %d\n", j, pole[j]); // vysledek spusteni bez volby ea: pro pole o 5 prvcich (0,4) Zadejte velikost pole: 5 Vypiste prvek na indexu: 5 java.lang.arrayindexoutofboundsexception: 5 at AssertArrayBoundsExample.osetreniMeziPole(AssertArrayBou ndsexample.java:13) at AssertArrayBoundsExample.main(AssertArrayBoundsExample.j ava:48) Detailni popis chyby - spustte s: -ea Strana 26 (celkem 31)

Příklad: Problém - dekompozice - program - ladění POMŮŽETE PASÁČKOVI? Pasáček hlídá na louce stádo koz. Kozy jsou méně či více vypasené (nejsou dvě stejné) a běhají různými rychlostmi. Jednoho kalného rána zavítá na louku hladový vlk. Prohlédne si všechny kozy a jak jinak, rozběhne se za tou nejvypasenější. Pokud bude koza rychlejší než vlk, tak mu samozřejmě uteče. Vlka však lov natolik vyčerpá, že si musí oddechnout a tak se znovu na louku vrátí až za dvě hodiny. A vše se opakuje. Protože je to ale chytrý vlk, nebude nikdy honit kozu, která mu už jednou utekla. Vybere si další nejvypasenější a zkusí to znovu. Chytí-li kozu, sežere ji a pak z louky odejde pryč. Pokud jsou kozy v dobré kondici a vlkovi se nepodaří za deset hodin některou z nich ulovit, odejde hladový lovit jinam. Kdyby měl pasáček k dispozici počítač a někdy už chodil na PPA1, mohl by si napsat program, který by mu řekl, je-li moudré stádo odehnat či, jak dlouho na louce setrvat. Poradíte pasáčkovi? Vstup Na prvním řádku je zadána celočíselná hodnota r v (0 > r v 50) reprezentující rychlost vlka. Na dalším řádku je zadán počet koz ve stádě p (1 p 15). Na dalších p řádkách je zadána vždy dvojice čísel, navzájem oddělených jednou mezerou, kde první z čísel reprezentuje vypasenost kozy v (1 v 15) a druhé číslo udává její rychlost r (1 r 15). Výstup Pokud bude vlk neúspěšný, vypište text: Vlk se nenazere, stado muze zustat!. Pokud nějakou kozu sežere, vypište text: Vlk by kozu sezral! na dalším řádku následovaný textem: Pasacek musí stado odehnat do: a počtem hodin, kdy bude stádo v bezpečí. Sežere-li vlk ovci ihned při prvním lovu, vypište text: Pasacek prijde o kozu!. Strana 27 (celkem 31)

Příklad vstupu 50 5 45 60 35 65 50 50 40 55 35 49 Příklad výstupu Pasacek prijde o kozu! Dekompozice: - vstup dat - vyber kozy - lov - výstup výsledku Struktura programu: Konstanty: - nejdelší doba lovu: 10 hodin - opakování lovu: po 2 hodinách - texty výsledku lovu Proměnné: - rychlost vlka - počet koz - kozy (hmotnost a rychlost) - dvourozměrné pole - počet hodin lovu Metody: - načtení vstupu - výběr kozy - lov - výpis výsledku Strana 28 (celkem 31)

import java.util.scanner; public class PasacekKoz { private static Scanner sc = new Scanner(System.in); static final int MAX_HODIN = 10; static String NEUSPECH = "Vlk se nenazere, stado muze zustat!"; static String USPECH_POZDEJI = "Vlk by sezral kozu! \npasacek musi stado odehnat do: "; static String USPECH_NAPOPRVE= "Pasacek prijde o kozu!"; static int [][] nactikozy(int pocetkoz){ int [][] kozy = new int[pocetkoz][2]; for(int i=0; i<kozy.length; i++){ kozy[i][0] = sc.nextint(); kozy[i][1] = sc.nextint(); return kozy; static int najdirychlostnejvypasenejsi(int[][] kozy){ int nejvypasenejsi = kozy[0][0]; //prvni int indexnejvypas = 0; for(int i=0; i<kozy.length; i++){ if(kozy[i][0] > nejvypasenejsi) { nejvypasenejsi = kozy[i][0]; // vaha nejvypasenejsi indexnejvypas = i; // index nejvypasenejsi if(kozy[indexnejvypas][0] > 0){ //nalezena kozy[indexnejvypas][0] = -1; // oznac - uz nehonit return kozy[indexnejvypas][1]; //vracena jeji rychlost else { return -1; //nenalezena (uz není zadna) Strana 29 (celkem 31)

static String lov(int rvlka, int kozy[][]){ String text = NEUSPECH; for(int pocethodin=0; pocethodin<=max_hodin; pocethodin += 2){ int rnejvypas = najdirychlostnejvypasenejsi(kozy); if(rnejvypas > 0){ // koza nalezena if(rnejvypas > rvlka){ // vlk je pomalejsi continue; // hledej dalsi kozu else { // uz neni dalsi koza text= NEUSPECH; // vlk nebude uspesny break; if(pocethodin > 0){ // vlk bude uspesny, pokud stado zustane text = USPECH_POZDEJI + pocethodin; break; else { // vlk sezere uz prvni kozu text = USPECH_NAPOPRVE; break; return text; static void vypis(string s){ System.out.println(s); Zadej rychlost vlka: 50 Zadej pocet koz: 5 Zadej hmotnosti a rychlosti koz: 45 60 35 65 50 50 40 55 35 49 Pasacek prijde o kozu! public static void main(string[] args) { System.out.print("Zadej rychlost vlka: "); int rvlka = sc.nextint(); System.out.print("Zadej pocet koz: "); int pocetkoz = sc.nextint(); System.out.println("Zadej hmotnosti a rychlosti koz: "); vypis(lov(rvlka, nactikozy(pocetkoz))); Strana 30 (celkem 31)

Návrh dat pro ladění programu: Existuje několik variant k prověření: Výběr dle hmotnosti (hledání maxima) a - rychlost každé z koz > rychlost vlka (neúspěch vlka) - rychlost jedné < rychlost vlka (úspěch vlka) - rychlost jedné = rychlost vlka (úspěch vlka) - rychlost více koz < rychlost vlka (úspěch vlka) Sledování doby lovu - rychlost první nejvypasenější rychlost vlka (sežere ji) - rychlost další (doba max) nejvypasenější rychlost vlka (stádo odehnat do spočtené doby) - rychlost další (doba > max) nejvypasenější rychlost vlka (stádo může zůstat) Počet koz - je jich dost na celou dobu lovu (možný úspěch) - je jich málo, tj. není-li další koza (neúspěch vlka) Zadej rychlost vlka: 50 Zadej pocet koz: 4 Zadej hmotnosti a rychlosti koz: 45 60 35 65 50 51 40 55 Vlk se nenazere, stado muze zustat! Zadej rychlost vlka: 50 Zadej pocet koz: 6 Zadej hmotnosti a rychlosti koz: 45 60 35 65 50 51 40 55 41 52 38 58 Vlk se nenazere, stado muze zustat! Zadej rychlost vlka: 50 Zadej pocet koz: 6 Zadej hmotnosti a rychlosti koz: 45 60 35 65 50 51 40 55 41 52 38 50 Vlk by sezral kozu! Pasacek musi stado odehnat do: 8 Zadej rychlost vlka: 50 Zadej pocet koz: 7 Zadej hmotnosti a rychlosti koz: 45 60 35 65 50 51 40 55 41 52 38 50 43 58 Vlk by sezral kozu! Pasacek musi stado odehnat do: 10 Zadej rychlost vlka: 50 Zadej pocet koz: 3 Zadej hmotnosti a rychlosti koz: 40 55 41 52 38 50 Vlk by sezral kozu! Pasacek musi stado odehnat do: 4 Zadej rychlost vlka: 50 Zadej pocet koz: 3 Zadej hmotnosti a rychlosti koz: 45 49 41 52 38 50 Pasacek prijde o kozu! atd. Strana 31 (celkem 31)