// Tässä määritellään muutamia omia poikkeustyyppejä. // Poikkeusluokissa on yleensä konstruktorit mutta niissä ei ole tietoja // tai muita metodeita. Näissä konstruktoreissa kutsutaan vain yliluokan // konstruktoria. class MyException extends Exception { public MyException() { super(); } public MyException(String s) { super(s); } } class MyOtherException extends Exception { public MyOtherException() { super(); } public MyOtherException(String s) { super(s); } } class MySubException extends MyException { public MySubException() { super(); } public MySubException(String s) { super(s); } } public class throwtest { // Tämä on main()-metodi. Huomaa, että siinä otetaan kahdella // erillisellä catch-lauseella kiinni kaksi Javan standardipoikkeusta. public static void main(String argv[]) { int i; // Muunnetaan argumentti ensin kokonaisluvuksi. // Varmistetaan, että argumentti on annettu ja että sen voi muuntaa. try { i = Integer.parseInt(argv[0]); } catch (ArrayIndexOutOfBoundsException e) { // argv on tyhjä System.out.println("Must specify an argument"); return; } catch (NumberFormatException e) { // argv[0] ei ole kokonaisluku System.out.println("Must specify an integer argument."); return; } // Annetaan argumentti metodille a(). a(i); } // Tässä metodissa kutsutaan metodia b(), jonka määrittelyssä on // kerrottu, että se voi aiheuttaa yhdenlaisen poikkeuksen. Varaudutaan // käsittelemään poikkeus. public static void a(int i) { try { b(i); } catch (MyException e) { // Kohta 1 // Tässä käsitellään MyException ja sen aliluokka MySubException. if (e instanceof MySubException) System.out.print("MySubException: "); else System.out.print("MyException: "); System.out.println(e.getMessage()); System.out.println("Handled at point 1"); } } // Tässä metodissa kutsutaan metodia c() ja käsitellään toiset metodin // mahdollisesti aiheuttamista poikkeuksista. Toisen tyyppisiä // poikkeuksia ei käsitellä joten ne siirtyvät kutsujan vastuulle ja ne // on esitelty tämän metodin throws-määreessä. Tässä metodissa on myös // finally-osa, jossa päätetään try-lohkossa tehty työ. Huomaa, että // finally-osa suoritetaan paikallisen catch-osan jälkeen mutta ennen // ulompaa catch-osaa tai sellaista catch-osaa, joka on tätä metodia // kutsuneessa metodissa. public static void b(int i) throws MyException { int result; try { System.out.print("i = " + i); result = c(i); System.out.print(" c(i) = " + result); } catch (MyOtherException e) { // Kohta 2 // Käsitellään MyOtherException-poikkeukset: System.out.println("MyOtherException: " + e.getMessage()); System.out.println("Handled at point 2"); } finally { // Lopetetaan yllä tehty tulostus rivinvaihdolla System.out.print("\n"); } } // Tässä metodissa lasketaan arvo tai aiheutetaan poikkeus. // throws-määreessä on lueteltu vain kaksi poikkeustyyppiä, koska // yksi poikkeuksista on toisen poikkeusluokan aliluokka. public static int c(int i) throws MyException, MyOtherException { switch (i) { case 0: // Suoritusta jatketaan kohdasta 1 throw new MyException("input too low"); case 1: // Suoritusta jatketaan kohdasta 1 throw new MySubException("input still too low"); case 99: // Suoritusta jatketaan kohdasta 2 throw new MyOtherException("input too high"); default: return i*i; } } }