java:exceptions_intro
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
java:exceptions_intro [2015/03/03 07:57] – [Δημιουργία ενός νέου τύπου εξαίρεσης και πυροδότηση εξαίρεσης] gthanos | java:exceptions_intro [2021/03/23 07:23] (current) – [Εξαιρέσεις (Exceptions)] gthanos | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== |
- | Σε αυτή την ενότητα θα αναφερθούμε σε αντικείμενα τα οποία δημιουργούνται κατά την ροή εκτέλεσης ενός προγράμματος, | + | Σε αυτή την ενότητα θα αναφερθούμε σε αντικείμενα τα οποία δημιουργούνται κατά την ροή εκτέλεσης ενός προγράμματος, |
- | Για να διασφαλίσουμε ότι το πρόγραμμά μας θα συνεχίσει την εκτέλεσή του ακόμη και αν συμβεί ένα απροσδόκητο γεγονός, | + | Για να διασφαλίσουμε ότι το πρόγραμμά μας θα συνεχίσει την εκτέλεσή του ακόμη και αν συμβεί ένα απροσδόκητο γεγονός, |
====== Αντικείμενο της εξαίρεσης (exception object) ====== | ====== Αντικείμενο της εξαίρεσης (exception object) ====== | ||
- | Οτιδήποτε υπάρχει στην γλώσσα Java δεν είναι κάτι διαφορετικό απο αντικείμενο. Έτσι, ακόμη και οι εξαιρέσεις που μπορούν να προκληθούν, | ||
- | Σε αυτό | + | Όταν προκληθεί |
- | <code java TestDivideByZero.java> | + | Σε αυτό το σημείο ας δούμε ένα πολύ απλό παράδειγμα λάθους που μπορεί να προκύψει αν δεν λάβει σχετική μέριμνα ο προγραμματιστής. |
- | import java.io.*; | + | |
- | import java.util.Scanner; | + | |
- | public class TestDivideByZero { | + | |
- | + | ||
- | | + | |
- | int x; | + | |
- | int y; | + | |
- | int result; | + | |
- | Scanner input = new Scanner(System.in); | + | |
- | System.out.print( "Enter first integer: " ); | + | <code java ExceptionHandling.java> |
- | x = input.nextInt(); | + | |
- | + | ||
- | System.out.print( "Enter second integer: " ); | + | |
- | y = input.nextInt(); | + | |
- | + | ||
- | result = x/y; | + | |
- | + | ||
- | System.out.printf( " | + | |
- | } | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Τι θα συμβεί στο παραπάνω πρόγραμμα αν ο 2ος αριθμός που θα δώσει ο χρήστης είναι 0; Επίσης αν ο χρήστης δεν δώσει αριθμό σαν είσοδο αλλά γράμμα; | + | |
- | + | ||
- | Όπως καταλαβαίνουμε, | + | |
- | + | ||
- | Στο παραπάνω παράδειγμα συνεπώς, | + | |
- | - να λάβουμε αυτό το αντικείμενο | + | |
- | - να δούμε το λάθος που έχει προκύψει | + | |
- | - να αντιμετωπίσουμε το λάθος έτσι ώστε το πρόγραμμά μας να επιστρέψει σε μια " | + | |
- | + | ||
- | ====== Try - catch block ====== | + | |
- | Στην προηγούμενη υποενότητα αναφερθήκαμε συνοπτικά στο αντικείμενο της εξαίρεσης. Εδώ θα δόυμε τον τρόπο με τον οποίο διαχειριζόμαστε τις εξαιρέσεις. | + | |
- | ==== Exception Handler ==== | + | |
- | Κάθε τμήμα του κώδικα που υπάρχει περίπτωση να πυροδοτήσει μια εξαίρεση θα πρέπει να την εμπερικλείουμε σε ένα try block. Το block αυτό του κώδικα θα περιγράφει τον τρόπο αντιμετώπισης της κάθε πιθανής εξαίρεσης που μπορεί να προκύψει. Ο ορισμός του block είναι ο εξής: | + | |
- | + | ||
- | <code java> | + | |
- | try{ | + | |
- | + | ||
- | /* | + | |
- | * code that may throw an exception here. | + | |
- | */ | + | |
- | + | ||
- | }catch (ExceptionTypeOne ex) { | + | |
- | + | ||
- | /* | + | |
- | * exception handler for ExceptionTypeOne objects. | + | |
- | */ | + | |
- | + | ||
- | }catch (ExceptionTypeTwo ex) { | + | |
- | + | ||
- | /* | + | |
- | * exception handler for ExceptionTypeOne objects. | + | |
- | */ | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Εντός του **try** block βάζουμε τον κώδικα που μπορεί να δημιουργηθεί μια εξαίρεση. Κάθε **catch** block ορίζει ένα διαφορετικό τύπο εξαίρεσης μέσα σε παρένθεση ('' | + | |
- | + | ||
- | Ας δούμε ένα μικρό τμήμα κώδικα που εντοπίζει ένα είδος εξαίρεσης το οποίο συναντήσαμε και παραπάνω: | + | |
- | + | ||
- | <code java TestDivideByZero.java> | + | |
- | import java.io.*; | + | |
import java.util.Scanner; | import java.util.Scanner; | ||
- | public class TestDivideByZero { | ||
- | |||
- | | ||
- | int x, y, result; | ||
- | | ||
- | Scanner input = new Scanner(System.in); | ||
- | System.out.print( "Enter first integer: " ); | + | public class ExceptionHandling |
- | x = input.nextInt(); | + | |
- | + | ||
- | System.out.print( "Enter second integer: " ); | + | |
- | y = input.nextInt(); | + | |
- | + | ||
- | try { | + | |
- | | + | |
- | | + | |
- | } catch (ArithmeticException ae) { | + | |
- | | + | |
- | if(y == 0){ | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Όπως βλέπουμε έχουμε το προηγούμενο παράδειγμα, | + | |
- | + | ||
- | === Ανοίγοντας ένα αρχείο για διάβασμα === | + | |
- | + | ||
- | Παρακάτω δίνεται ένα πιο σύνθετο παράδειγμα μία μεθόδου που διαβάζει ένα αρχείο κειμένου και το επιστρέφει στη μορφή ενός String. | + | |
- | + | ||
- | <code java WholeFileReader.java> | + | |
- | import java.io.*; | + | |
- | import java.lang.*; | + | |
- | + | ||
- | public class WholeFileReader | + | |
| | ||
- | | + | public static void main(String []args) { |
- | + | ||
- | try { | + | |
- | File file = new File (path); | + | |
- | FileReader fReader = new FileReader(file); | + | |
- | BufferedReader in = new BufferedReader(fReader); | + | |
- | String inputLine; | + | |
- | StringBuffer strDocument = new StringBuffer(); | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | //throw new IOException(); | + | |
- | } | + | |
- | System.out.println(" | + | |
- | fReader.close(); | + | |
- | return strDocument.toString(); | + | |
- | } | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | return ""; | + | |
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | return " | + | |
- | } | + | |
- | + | ||
- | | + | |
- | WholeFileReader wfr = new WholeFileReader(); | + | |
- | try { | + | |
- | System.out.println(wfr.readFile(args[0]) ); | + | |
- | } | + | |
- | catch(IndexOutOfBoundsException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Παρατηρήστε ότι εμφανίζονται δύο **catch** blocks. Το πρώτο catch block αφορά [[http:// | + | |
- | + | ||
- | <code java> | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | return ""; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | καθώς ο μη εντόπισμός αρχείου θα ενέπιπτε σε '' | + | |
- | + | ||
- | Επίσης, | + | |
- | <code java> | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | return ""; | + | |
- | } | + | |
- | </ | + | |
- | Σε αυτή την περίπτωση, | + | |
- | + | ||
- | Τέλος, στο παραπάνω παράδειγμα βγάλτε τα σχόλια από την γραμμή '' | + | |
- | <code java> | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | //throw new IOException(); | + | |
- | } | + | |
- | </ | + | |
- | για να δημιουργήσετε ένα '' | + | |
- | + | ||
- | ==== Finaly Block ==== | + | |
- | + | ||
- | Εκτός από τα **catch** blocks τα οποία εκτελούνται όταν έχουμε κάποιο exception, μπορούμε να προσθέσουμε ένα finaly block το οποίο θα εκτελεστεί __σε κάθε περίπτωση__. Το finaly block θα εκτελεστεί στις παρακάτω περιπτώσεις: | + | |
- | * Εάν προκύψει η εξαίρεση που έχουμε φροντίσει να διαχειριστούμε (στο παρακάτω παράδειγμα FileNotFoundException). | + | |
- | * Εάν προκύψει μια εξαίρεση ενός τύπου που δεν έχουμε φροντίσει να διαχειριστούμε. | + | |
- | * Εάν δεν προκύψει καμία απολύτως εξαίρεση. | + | |
- | + | ||
- | Δείτε το παρακάτω παράδειγμα όπου ενσωματώνει ένα **finally** block. | + | |
- | <code java> | + | |
- | import java.io.*; | + | |
- | import java.lang.*; | + | |
- | + | ||
- | public class WholeFileReader { | + | |
- | + | ||
- | public String readFile(String path) { | + | |
- | + | ||
- | FileReader fReader = null; | + | |
- | try { | + | |
- | File file = new File (path); | + | |
- | fReader = new FileReader(file); | + | |
- | BufferedReader in = new BufferedReader(fReader); | + | |
- | String inputLine; | + | |
- | StringBuffer strDocument = new StringBuffer(); | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | //throw new IOException(); | + | |
- | } | + | |
- | fReader.close(); | + | |
- | return strDocument.toString(); | + | |
- | } | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | return ""; | + | |
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | finally { | + | |
- | if(fReader!=null) { | + | |
- | try{ | + | |
- | System.out.println(" | + | |
- | fReader.close(); | + | |
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | else { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | return ""; | + | |
- | } | + | |
- | + | ||
- | public static void main(String args[]) { | + | |
- | WholeFileReader wfr = new WholeFileReader(); | + | |
- | try { | + | |
- | System.out.println(wfr.readFile(args[0]) ); | + | |
- | } | + | |
- | catch(IndexOutOfBoundsException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Ο λόγος που συνήθως χρησιμοποιήσουμε το **finally** block είναι για να συμπεριλάβουμε κώδικα που θέλουμε να εκτελεστεί σε όλες τις περιπτώσεις, | + | |
- | + | ||
- | Στο παραπάνω παράδειγμα δείτε την πορεία του κώδικα βγάζοντας τα σχόλια και βάζοντας σε σχόλια την γραμμή που δημιουργεί το '' | + | |
- | <code java> | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | //throw new IOException(); | + | |
- | } | + | |
- | </ | + | |
- | ====== Χειρισμός της εξαίρεσης σε υψηλότερο επίπεδο ====== | + | |
- | + | ||
- | Στην προηγούμενη ενότητα δείξαμε πως μπορούμε να χειριστούμε μια εξαίρεση όταν προκύπτει. Η Java μας δίνει την δυνατότητα να μην διαχειριστούμε την εξαίρεση μέσα στην μέθοδο που προκύπτει, | + | |
- | + | ||
- | - Κατ' | + | |
- | - Στην συνέχεια κάνουμε comment-out τις γραμμές που ελέγχουν το '' | + | |
- | - Τέλος διαχειριζόμαστε την εξαίρεση μέσα στη μέθοδο '' | + | |
- | + | ||
- | <code java> | + | |
- | + | ||
- | import java.io.*; | + | |
- | import java.lang.*; | + | |
- | + | ||
- | public class WholeFileReader { | + | |
- | + | ||
- | public String readFile(String path) throws FileNotFoundException { | + | |
- | FileReader fReader = null; | + | |
- | + | ||
- | try { | + | |
- | File file = new File (path); | + | |
- | fReader = new FileReader(file); | + | |
- | BufferedReader in = new BufferedReader(fReader); | + | |
- | String inputLine; | + | |
- | StringBuffer strDocument = new StringBuffer(); | + | |
- | try { | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | return strDocument.toString(); | + | |
- | } | + | |
- | /* //Remove exception from here. Handle it at a higher level | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | }*/ | + | |
- | finally { | + | |
- | if( fReader != null) { | + | |
- | try { | + | |
- | System.out.println(" | + | |
- | fReader.close(); | + | |
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | } | + | |
| | ||
- | } | + | Scanner sc = new java.util.Scanner(System.in); |
- | + | ||
- | public static void main(String args[]) { | + | |
- | WholeFileReader wfr = new WholeFileReader(); | + | |
- | try { | + | |
- | System.out.println(wfr.readFile(args[0]) ); | + | |
- | } | + | |
- | catch(IndexOutOfBoundsException ex) { | + | |
- | | + | |
- | } | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Στον παραπάνω κώδικα βλέπουμε την περίπτωση στην οποία __δεν__ διαχειριζόμαστε την εξαίρεση εντός της μεθόδου '' | + | |
- | * εάν δεν διαχειριστούμε τον συγκεκριμένο τύπο Exception στην μέθοδο από την οποία καλούμε την μέθοδο με την δήλωση **throw**. | + | |
- | * ή εάν δεν έχουμε μία δήλωση **throw** για το συγκεκριμένο τύπο Exception στην δήλωση της μεθόδου από την οποία καλούμε την εν λόγω μέθοδο. | + | |
- | + | ||
- | ====== Δημιουργία ενός νέου τύπου εξαίρεσης και πυροδότηση εξαίρεσης ====== | + | |
- | Στις προηγούμενες ενότητες είδαμε τον τρόπο με τον οποίο χειριζόμαστε μια εξαίρεση. Μέχρι αυτό το σημείο έχουμε αναφερθεί σε εξαιρέσεις που παρέχονται από κλάσεις του συστήματος. Πως όμως δημιουργούνται αυτές οι εξαιρέσεις και πως και εμείς μπορούμε να καλέσουμε μια εξαίρεση; | + | |
- | + | ||
- | Επανερχόμενοι στο παράδειγμα ανάγνωσης ενός αρχείου ας υποθέσουμε ότι θέλουμε να δημιουργούμε μία εξαίρεση αν το αρχείο είναι άδειο, δηλ δεν περιέχει κανένα χαρακτήρα. Για τον σκοπό αυτό δημιουργούμε ένα νέο τύπο εξαίρεσης με όνομα '' | + | |
- | + | ||
- | <code java EmptyFileException.java> | + | |
- | public class EmptyFileException extends java.lang.Exception { | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Όπως τονίσαμε και παραπάνω η εξαίρεση είναι και αυτή ένα αντικείμενο. Για να καλέσουμε ένα αντικείμενο εξαίρεσης το μόνο που έχουμε να κάνουμε είναι να βάλουμε τη δεσμευμένη λέξη **throw** και δίπλα το αντικείμενο της εξαίρεσης που θέλουμε να καλέσουμε. Στο παρακάτω παράδειγμα, | + | |
- | + | ||
- | <code java > | + | |
- | import java.io.*; | + | |
- | import java.lang.*; | + | |
- | + | ||
- | public class WholeFileReader { | + | |
- | + | ||
- | public String readFile(String path) throws FileNotFoundException, | + | |
- | FileReader fReader = null; | + | |
- | + | ||
- | try { | + | |
- | File file = new File (path); | + | |
- | fReader = new FileReader(file); | + | |
- | BufferedReader | + | |
- | String inputLine; | + | |
- | StringBuffer strDocument = new StringBuffer(); | + | |
- | try { | + | |
- | while ((inputLine = in.readLine()) != null) { | + | |
- | strDocument.append(inputLine); | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | catch(IOException ex) { | + | |
- | System.out.println(" | + | |
- | } | + | |
- | if( strDocument.toString().isEmpty() ) { | + | |
- | throw new EmptyFileException(); | + | |
- | } | + | |
- | return strDocument.toString(); | + | |
- | } | + | |
| | ||
- | | + | System.out.print("Width: |
- | if( fReader != null) { | + | int width = sc.nextInt(); |
- | try { | + | System.out.print("Height: |
- | //System.out.println("Closing file"); | + | |
- | | + | |
- | } | + | System.out.format("Ratio: %.2f", ratio); |
- | catch(IOException ex) { | + | |
- | | + | } |
- | } | + | |
- | } | + | |
- | | + | |
- | + | ||
- | } | + | |
- | + | ||
- | public static void main(String args[]) { | + | |
- | WholeFileReader wfr = new WholeFileReader(); | + | |
- | | + | |
- | System.out.println(wfr.readFile(args[0]) | + | |
- | | + | |
- | catch(IndexOutOfBoundsException ex) { | + | |
- | | + | |
- | } | + | |
- | catch(FileNotFoundException ex) { | + | |
- | System.out.println("The specified file was not found at "+ args[0]); | + | |
- | | + | |
- | catch(EmptyFileException ex) { | + | |
- | System.out.println("File is empty!!!" | + | |
- | } | + | |
- | } | + | |
} | } | ||
</ | </ | ||
+ | Τι θα συμβεί στο παραπάνω πρόγραμμα αν ο χρήστης αντί για ακέραιο δώσει μία σειρά από γράμματα ή αν κλείσει την εισαγωγή χαρακτήρων από το πληκτρολόγιο πατώντας CTRL+D. | ||
+ | Ο προγραμματιστής καλείται να προβλέψει τις παραπάνω περιπτώσεις στις οποίες ο χρήστης θα δώσει μη κατάλληλη είσοδο. Στο παράδειγμα , το σύστημα θα παράξει ένα αντικείμενο που θα περιγράφει το είδος του λάθους που συνέβη. Ο κώδικας του προγράμματος πρέπει: | ||
+ | - να λάβει το αντικείμενο | ||
+ | - να εξετάσει το λάθος που έχει προκύψει | ||
+ | - να αντιμετωπίσει το λάθος, ώστε το πρόγραμμά να επιστρέψει σε ένα σημείο από όπου μπορεί να συνεχίσει τη λειτουργία του χωρίς πρόβλημα. | ||
+ | |Προηγούμενο: | ||
- |
java/exceptions_intro.1425369478.txt.gz · Last modified: 2015/03/03 07:57 by gthanos