Χειρισµός Σφαλµάτων Γρηγόρης Τσουµάκας Τµήµα Πληροφορικής, Αριστοτέλειο Πανεπιστήµιο Θεσσαλονίκης Έκδοση: 2010.12.06
Σφάλµατα, Σφάλµατα, Σφάλµατα 2 εν υπάρχουν προγράµµατα χωρίς λογικά λάθη Υλοποίηση που δεν συµφωνεί µε τις προδιαγραφές Π.χ. υπολογισµός της µέση τιµής αντί για τη διάµεσο Εσφαλµένη κλήση της µεθόδου ενός αντικειµένου Π.χ. παράµετρος εκτός έγκυρου εύρους Ασυνεπής ή ακατάλληλη κατάσταση αντικειµένου Π.χ. µπορεί να προκύψει µέσω κληρονοµικότητας Σφάλµατα εκτός του ελέγχου του προγραµµατιστή Λάθος διεύθυνση URL σε έναν browser ικτυακό σφάλµα σύνδεσης Λάθος όνοµα αρχείου, λάθος δικαιώµατα πρόσβασης
Τι Κάνουµε για τα Σφάλµατα; 3 Αµυντικός προγραµµατισµός Πρόβλεψη των σφαλµάτων που µπορεί να προκληθούν και αποφυγή τους Αναφορά σφαλµάτων όταν προκύπτουν Χειρισµός και παραγωγή εξαιρέσεων
Αµυντικός Προγραµµατισµός 4 Αλληλεπίδραση αντικειµένων Ένα αντικείµενο πελάτης (client) δηµιουργεί και καλεί µεθόδους ενός αντικειµένου διακοµιστή (server) Πιθανές υποθέσεις προγραµµατιστών διακοµιστή Τα αντικείµενα πελάτες θα συµπεριφέρονται σωστά Τα αντικείµενα πελάτες θα είναι εχθρικά Αµυντικός προγραµµατισµός Έλεγχος των παραµέτρων που στέλνει ο πελάτης κατά την δηµιουργία αντικειµένων και την κλήση µεθόδων µε σκοπό την αποφυγή σφαλµάτων exceptions.students1, exceptions.students2
Αναφορά των Σφαλµάτων 5 Ειδοποίηση του χρήστη Πολλές εφαρµογές εκτελούνται χωρίς επίβλεψη από κάποιο χρήστη Ακόµα και αν υπάρχει χρήστης, αυτός συνήθως δεν µπορεί να κάνει κάτι για το σφάλµα Ειδοποίηση του αντικειµένου πελάτη Επιστροφή τιµής από την κλήση της µεθόδου Παραγωγή µιας εξαίρεσης
Επιστροφή Τιµής 6 Τιµή που επιστρέφεται Αν η µέθοδος ήταν void Επιστροφή λογικής τιµής που φανερώνει αν πήγαν όλα καλά Αν επιστρέφει αντικείµενο Επιστροφή τιµής null για να επισηµάνουµε πρόβληµα Αν επιστρέφει αριθµό Όµως Επιστροφή αριθµού εκτός αναµενόµενων ορίων exceptions.students3 εν µπορεί κανείς να αναγκάσει τον προγραµµατιστή να ελέγξει την επιστρεφόµενη τιµή Μια µόνο τιµή δεν φτάνει για διαφορετικά λάθη που απαιτούν διαφορετική αντιµετώπιση Κωδικός σφάλµατος, κλήση µε αναφορά για επιστροφή τιµών
Εξαιρέσεις και Ρίψη Εξαιρέσεων 7 Εξαίρεση (exception) Σφάλµα που συµβαίνει κατά την εκτέλεση ενός προγράµµατος και διακόπτει τη φυσιολογική ροή των εντολών του Ρίψη εξαίρεσης (throwing an exception) throw αντικείµενοεξαίρεσης Όταν συµβεί ένα σφάλµα µέσα σε µία µέθοδο, τότε αυτή δηµιουργεί ένα αντικείµενο εξαίρεσης µε πληροφορίες (είδος σφάλµατος, κατάσταση του προγράµµατος, κ.α.) για αυτό το σφάλµα, και στη συνέχεια το παραδίδει στο σύστηµα χρόνου εκτέλεσης (runtime system) exceptions.students4
Αναζήτηση Χειριστή 8 Το σύστηµα χρόνου εκτέλεσης αναζητεί στη στοίβα κλήσεων (call stack) να βρει αν ο κώδικας που οδήγησε στην εξαίρεση βρίσκεται µέσα σε ένα block κώδικα που παρακολουθείται για εξαιρέσεις και αν αυτό συνοδεύεται από κατάλληλο χειριστή (exception handler) για τη συγκεκριµένη εξαίρεση
Παρακολούθηση και Χειρισµός 9 Παρακολούθηση και χειρισµός εξαιρέσεων Η διαχείριση εξαιρέσεων απαιτεί ένα τµήµα κώδικα που παρακολουθείται για εξαιρέσεις (try) και ένα (ή παραπάνω) που µπορεί να χειριστεί εξαιρέσεις (catch) Τα δύο αυτά τµήµατα πάντα υπάρχουν ως ζεύγος Τµήµατα try/catch try { // κώδικας που παρακολουθείται // για εµφάνιση σφαλµάτων catch (ExceptionType exception) { // χειριστής για εξαίρεση ExceptionType
Καταλληλότητα Χειριστή 10 Κατάλληλος χειριστής εξαίρεσης Ένας χειριστής είναι κατάλληλος για µια εξαίρεση αν ο τύπος του αντικειµένου της ταιριάζει (είναι ίδιος ή υποκλάση) µε τον τύπο που αυτός µπορεί να χειριστεί Αν βρεθεί κατάλληλος χειριστής Τότε λέµε ότι συλλαµβάνει (catches) την εξαίρεση Εκτελείται ο κώδικας του και η ροή της εκτέλεσης συνεχίζει µετά το πέρας του try/catch Αν δε βρεθεί (κατάλληλος) χειριστής, Τότε η εξαίρεση θα συλληφθεί από την JVM, µε συνέπεια να σταµατήσει µόνιµα η εκτέλεση του προγράµµατος και να εµφανιστεί το ίχνος της στοίβας κλήσεων και ένα µήνυµα µε πληροφορίες για το σφάλµα
Ορισµένα Πρώτα Παραδείγµατα 11 Μη εύρεση χειριστή exceptions.example1a Εύρεση ακατάλληλου χειριστή exceptions.example1b Εύρεση κατάλληλου χειριστή Εκεί που προκλήθηκε η εξαίρεση Σε προηγούµενη κλήση (προώθηση εξαίρεσης) exceptions.example1c, exceptions.example1d, exceptions.students5, exceptions.aircond
Είδη Εξαιρέσεων (1/3) 12 Η κλάση Throwable Ένα αντικείµενο εξαίρεσης (πρέπει να) ανήκει σε κλάση που κληρονοµεί την κλάση Throwable Έχει δύο παιδιά, τις κλάσεις Error και Exception Εξαιρέσεις της κλάσης Error εν οφείλονται στην εφαρµογή που εκτελείται Συνήθως είναι µη αναµενόµενες και χωρίς δυνατότητα ανάκαµψης (διόρθωσης του σφάλµατος) Π.χ. αδυναµία ανάγνωσης ενός αρχείου που υπάρχει στο σύστηµα λόγω προβλήµατος στο υλικό Ωστόσο αν προσδιορίσουµε χειριστή, αποφεύγουµε το κρέµασµα της εφαρµογής εν µπορούµε να ορίσουµε τέτοιες δικές µας εξαιρέσεις
Είδη Εξαιρέσεων (2/3) 13 Εξαιρέσεις της κλάσης Exception Οφείλονται στην εφαρµογή που εκτελείται ιακρίνονται σε α) µη αναµενόµενα λογικά σφάλµατα, και β) σε σφάλµατα που ενδέχεται να προκύψουν Μη αναµενόµενα λογικά σφάλµατα Θα πρέπει να διορθώνονται ώστε να µην εµφανίζονται Συνήθως δεν υπάρχει δυνατότητα ανάκαµψης (διόρθωσης του σφάλµατος), όµως αν προσδιορίσουµε χειριστή, αποφεύγουµε το κρέµασµα της εφαρµογής Η υποκλάση RuntimeException της κλάσης Exception Περιέχει έναν αριθµό από έτοιµες τέτοιες εξαιρέσεις, όπως υπέρβαση ορίων πίνακα, ακέραια διαίρεση µε το 0 Ορίζουµε δικές µας εξαιρέσεις επεκτείνοντας την κλάση αυτή
Είδη Εξαιρέσεων (3/3) 14 Σφάλµατα που ενδέχεται να προκύψουν Π.χ. ο χρήστης δίνει ένα όνοµα αρχείου για άνοιγµα, το οποίο δεν υπάρχει στο σύστηµα Υπάρχει πάντα τρόπος να ανακάµψουµε από αυτά Μια καλοσχεδιασµένη εφαρµογή οφείλει να έχει χειριστές και να ανακάµπτει από τέτοια σφάλµατα Ορίζουµε δικές µας εξαιρέσεις αυτού του είδους επεκτείνοντας την κλάση Exceptions
Υποχρέωση Χειρισµού 15 Ανέλεγκτες εξαιρέσεις (unchecked) O compiler της Java δεν απαιτεί την ύπαρξη κώδικα χειρισµού για εξαιρέσεις που ανήκουν στις κλάσεις Error και RuntimeException εν θα έπρεπε να προκύψουν και δεν µπορούµε πάντα να κάνουµε κάτι για να τις διορθώσουµε Ελεγµένες εξαιρέσεις (checked) Ο compiler της Java απαιτεί την ύπαρξη χειριστή όλων των υπόλοιπων εξαιρέσεων (όσων ανήκουν στην κλάση Exception, όχι όµως και στην RuntimeException) Είναι αναµενόµενες και υπάρχει τρόπος ανάκαµψης Υποχρεώνουµε τον προγραµµατιστή να τις λάβει υπόψη
Μερικά Ακόµα Παραδείγµατα 16 Παραδείγµατα RuntimeException Χειρισµός τους ιόρθωση τους για αποφυγή εµφάνισης τους exceptions.example3 Παραδείγµατα Exception Υποχρέωση χειρισµού τους Χειρισµός τους στο σηµείο της εξαίρεσης Ο χειρισµός σε προηγούµενη κλήση απαιτεί τη χρήση της λέξης κλειδί throws (µη αυτόµατη προώθηση) πριν την έναρξη του κώδικα της µεθόδου exceptions.example4
Σύλληψη Εξαιρέσεων 17 Πολλαπλοί χειριστές Ένας χειριστής εξαιρέσεων µπορεί να αποτελείται από πολλαπλά catch, τα οποία εξετάζονται µε τη σειρά που γράφονται µέσα στο πρόγραµµα exceptions.example5 Σύλληψη µέσω υπερκλάσης Ένας χειριστής εξαιρέσεων κάποιου τύπου, µπορεί να συλλάβει οποιαδήποτε εξαίρεση είτε αυτού του τύπου είτε των υποκλάσεων του exceptions.example6
Γιατί Σύλληψη µέσω Υπερκλάσης; 18 Περίπτωση 1 Όταν είναι σηµαντικό να αποφευχθεί ο τερµατισµός εκτέλεσης της εφαρµογής, τότε προτείνεται η χρήση ενός χειριστή εξαίρεσης τύπου Throwable, ο οποίος θα πιάσει οποιαδήποτε εξαίρεση Περίπτωση 2 Όταν ο ίδιος κώδικας µπορεί να χειριστεί ένα σύνολο διαφορετικών εξαιρέσεων, τότε προτείνεται η χρήση ενός χειριστή εξαίρεσης για την υπερκλάση αυτών των εξαιρέσεων, για την αποφυγή της διπλοκαταχώρησης κώδικα
Τελικό Τµήµα Κώδικα 19 finally Ένα block κώδικα finally µπαίνει στο τέλος ενός try/catch block και εκτελείται πάντα µετά την ολοκλήρωση του try/catch Είτε προκύψει εξαίρεση, είτε όχι, είτε ζητηθεί επιστροφή από τη µέθοδο µε return Χρησιµεύει για ρύθµιση εκκρεµοτήτων Π.χ. ανοικτό αρχείο, ανοικτή διαδικτυακή σύνδεση exceptions.example8, exceptions.example9
ηµιουργία Εξαίρεσης 20 ηµιουργία εξαίρεσης Μπορείτε να δηµιουργήσετε τις δικές σας νέες εξαιρέσεις επεκτείνοντας την κατάλληλη κλάση exceptions.nonintdivexception, exceptions.example10
Πλεονεκτήµατα Εξαιρέσεων 21 ιαχωρισµός του κώδικα χειρισµού σφαλµάτων από τον φυσιολογικό κώδικα Προώθηση σφαλµάτων στη στοίβα κλήσεων Οµαδοποίηση και διαχωρισµός ειδών σφαλµάτων
ιαχωρισµός Κώδικα (1/3) 22 Έστω ο παρακάτω κώδικας για την ανάγνωση ενός αρχείου readfile { open the file; read the file into memory; close the file;
ιαχωρισµός Κώδικα (2/3) 23 errorcodetype readfile { initialize errorcode = 0; open the file; if (thefileisopen) { read the file into memory; if (readfailed) { errorcode = -1; close the file; if (thefiledidntclose && errorcode == 0) { errorcode = -4; else { errorcode = -3; else { errorcode = -5; return errorcode;
ιαχωρισµός Κώδικα (3/3) 24 readfile { try { open the file; read the file into memory; close the file; catch (fileopenfailed) { dosomething; catch (readfailed) { dosomething; catch (fileclosefailed) { dosomething;
Προώθηση Σφαλµάτων (1/4) 25 Έστω ο παρακάτω κώδικας όπου µόνο η method1 ενδιαφέρεται για σφάλµατα στη readfile method1 { call method2; method2 { call method3; method3 { call readfile;
Προώθηση Σφαλµάτων (2/4) 26 errorcodetype method3 { errorcodetype error; error = call readfile; if (error) return error; errorcodetype method2 { errorcodetype error; error = call method3; if (error) return error;
Προώθηση Σφαλµάτων (3/4) 27 method1 { errorcodetype error; error = call method2; if (error) doerrorprocessing;
Προώθηση Σφαλµάτων (4/4) 28 method1 { try { call method2; catch (exception e) { doerrorprocessing; method2 throws exception { call method3; method3 throws exception { call readfile;
Οµαδοποίηση και ιαχωρισµός (I) 29 Οι εξαιρέσεις είναι αντικείµενα, τα οποία ανήκουν σε µια ιεραρχία κλάσεων µε πρόγονο κλάση την Throwable Αυτό µας δίνει τη δυνατότητα να χειριστούµε οµαδικά κάποια σφάλµατα µε βάση την υπερκλάση τους
Οµαδοποίηση και ιαχωρισµός (ΙΙ) 30 catch (EOFException e) { // ιάβασµα πέρα από το τέλος του αρχείου catch (FileNotFoundException e) { // εν βρέθηκε το αρχείο catch (IOException e) { // Γενική διαχείριση σφαλµάτων Ι/Ο catch (Throwable e) { // Συλλαµβάνει όλα τα λάθη