This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision Last revision Both sides next revision | ||
|
java:exceptions_try_catch_block [2017/02/06 13:56] gthanos [Διαχείριση Εξαιρέσεων] |
java:exceptions_try_catch_block [2021/03/23 07:26] gthanos [Παράδειγμα] |
||
|---|---|---|---|
| Line 3: | Line 3: | ||
| ===== Try-Catch Block ===== | ===== Try-Catch Block ===== | ||
| - | Κάθε τμήμα του κώδικα που υπάρχει περίπτωση να πυροδοτήσει μια εξαίρεση θα πρέπει να την εμπερικλείουμε σε ένα **try block**. Το block αυτό του κώδικα θα περιγράφει τον τρόπο αντιμετώπισης της κάθε πιθανής εξαίρεσης που μπορεί να προκύψει. Ο ορισμός του block είναι ο εξής: | + | |
| + | Κάθε τμήμα του κώδικα που υπάρχει περίπτωση να πυροδοτήσει μια εξαίρεση θα πρέπει να το περικλείουμε σε ένα **try block**. Το block αυτό του κώδικα περιγράφει τον τρόπο αντιμετώπισης της κάθε πιθανής εξαίρεσης που μπορεί να προκύψει. Ο ορισμός του block είναι ο εξής: | ||
| <code java> | <code java> | ||
| Line 27: | Line 28: | ||
| </ | </ | ||
| - | Εντός του **try** block βάζουμε τον κώδικα που μπορεί να δημιουργηθεί μια εξαίρεση. Κάθε **catch** block ορίζει ένα διαφορετικό τύπο εξαίρεσης μέσα σε παρένθεση ('' | + | Εντός του **try** block βάζουμε τον κώδικα που μπορεί να δημιουργηθεί μια εξαίρεση. Κάθε **catch** block ορίζει ένα διαφορετικό τύπο εξαίρεσης μέσα σε παρένθεση ('' |
| - | Ας δούμε ένα μικρό τμήμα κώδικα που εντοπίζει ένα είδος εξαίρεσης το οποίο συναντήσαμε και παραπάνω: | + | ==== Παράδειγμα ==== |
| - | <code java TestDivideByZero.java> | + | Στο προηγούμενο πρόγραμμα ας δούμε ποιοι τύποι εξαιρέσεων προκύπτουν με βάση τη λανθασμένη είσοδο του χρήστη. Στην περίπτωση που ο χρήστης εισάγει γράμματα αντί για ψηφία θα προκύψει μία εξαίρεση του τύπου [[https:// |
| - | import java.io.*; | + | |
| - | import | + | |
| - | public class TestDivideByZero { | + | |
| - | + | ||
| - | | + | |
| - | int x, y, result; | + | |
| - | + | ||
| - | Scanner input = new Scanner(System.in); | + | |
| - | System.out.print( "Enter first integer: " ); | + | Παρατηρήστε επίσης ότι η κλάση [[https:// |
| - | x = input.nextInt(); | + | |
| - | System.out.print( "Enter second integer: " ); | + | Παρακάτω δίνεται το προηγούμενο πρόγραμμα εμπλουτισμένο με κώδικα για τη διαχείριση των πιθανών εξαιρέσεων. |
| - | y = input.nextInt(); | + | |
| - | + | ||
| - | try { | + | |
| - | | + | |
| - | | + | |
| - | } catch (ArithmeticException ae) { | + | |
| - | | + | |
| - | if(y == 0){ | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | } | + | |
| - | } | + | |
| - | </ | + | |
| - | Όπως βλέπουμε έχουμε το προηγούμενο παράδειγμα, | + | <code java ExceptionHandling.java> |
| + | import java.util.Scanner; | ||
| + | import java.util.NoSuchElementException; | ||
| + | import java.util.InputMismatchException; | ||
| - | === Ανοίγοντας ένα αρχείο για διάβασμα === | + | public class ExceptionHandling |
| - | + | ||
| - | Παρακάτω δίνεται ένα πιο σύνθετο παράδειγμα μία μεθόδου που διαβάζει ένα αρχείο κειμένου και το επιστρέφει στη μορφή ενός String. | + | |
| - | + | ||
| - | <code java WholeFileReader.java> | + | |
| - | import java.io.*; | + | |
| - | import java.lang.*; | + | |
| - | + | ||
| - | public class WholeFileReader | + | |
| | | ||
| - | public | + | public |
| + | |||
| + | Scanner sc = new java.util.Scanner(System.in); | ||
| + | | ||
| try { | try { | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | sc.close(); |
| - | // | + | } catch(InputMismatchException ex) { |
| - | } | + | System.out.println(" |
| - | System.out.println(" | + | } catch(NoSuchElementException ex) { |
| - | | + | |
| - | | + | |
| } | } | ||
| - | catch(FileNotFoundException ex) { | ||
| - | System.out.println(" | ||
| - | return ""; | ||
| - | } | ||
| - | catch(IOException ex) { | ||
| - | 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(" | ||
| - | } | ||
| - | } | ||
| - | |||
| } | } | ||
| </ | </ | ||
| - | Παρατηρήστε | + | <WRAP tip 80% center round> |
| + | Η σειρά διαχείρισης των εξαιρέσεων έχει σημασία. Εφόσον, δημιουργηθεί μία εξαίρεση, | ||
| - | < | + | Εάν επιχειρήσετε να αντιμεταθέσετε τα δύο catch blocks αυτό που θα συμβεί είναι να λάβετε ένα μήνυμα λάθους από τον μεταγλωττιστή. Ο λόγος είναι ότι επειδή η κλάση InputMismatchException είναι υποκλάση της [[https:// |
| - | | + | </WRAP> |
| - | System.out.println(" | + | |
| - | return ""; | + | |
| - | } | + | |
| - | </code> | + | |
| - | καθώς ο μη εντόπισμός αρχείου θα ενέπιπτε σε '' | ||
| - | Επίσης, | + | ===== Finaly Block ===== |
| - | <code java> | + | |
| - | catch(IOException ex) { | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | catch(FileNotFoundException ex) { | + | |
| - | System.out.println(" | + | |
| - | return ""; | + | |
| - | } | + | |
| - | </ | + | |
| - | Σε αυτή την περίπτωση, | + | |
| - | Τέλος, στο παραπάνω | + | Στον παραπάνω |
| - | < | + | |
| - | while ((inputLine = in.readLine()) != null) { | + | |
| - | strDocument.append(inputLine); | + | |
| - | //throw new IOException(); | + | |
| - | } | + | |
| - | </ | + | |
| - | για να δημιουργήσετε ένα '' | + | |
| - | ===== Finaly Block ===== | + | Η κλήση |
| - | + | ||
| - | Εκτός από τα **catch** blocks τα οποία εκτελούνται όταν έχουμε κάποιο exception, μπορούμε να προσθέσουμε ένα **finaly block** | + | |
| * Εάν προκύψει η εξαίρεση που έχουμε φροντίσει να διαχειριστούμε (στο παρακάτω παράδειγμα // | * Εάν προκύψει η εξαίρεση που έχουμε φροντίσει να διαχειριστούμε (στο παρακάτω παράδειγμα // | ||
| - | * Εάν προκύψει μια εξαίρεση ενός τύπου που δεν έχουμε φροντίσει να διαχειριστούμε. | + | * Εάν προκύψει μια εξαίρεση ενός τύπου που δεν έχουμε φροντίσει να διαχειριστούμε, εντός των υφιστάμενων catch blocks. |
| * Εάν δεν προκύψει καμία απολύτως εξαίρεση. | * Εάν δεν προκύψει καμία απολύτως εξαίρεση. | ||
| - | Δείτε το παρακάτω | + | Δείτε το προηγούμενο |
| - | <code java WholeFileReader.java> | + | |
| - | import java.io.*; | + | |
| - | import java.lang.*; | + | |
| - | public class WholeFileReader | + | <code java ExceptionHandling.java> |
| + | import java.util.Scanner; | ||
| + | import java.util.NoSuchElementException; | ||
| + | import java.util.InputMismatchException; | ||
| + | |||
| + | public class ExceptionHandling | ||
| | | ||
| - | public | + | public |
| - | + | ||
| - | | + | |
| + | | ||
| try { | try { | ||
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | StringBuffer strDocument | + | |
| - | | + | |
| - | strDocument.append(inputLine); | + | } catch(InputMismatchException |
| - | | + | System.out.println(" |
| - | | + | } catch(NoSuchElementException |
| - | return strDocument.toString(); | + | System.out.println(" |
| - | } | + | |
| - | | + | |
| - | System.out.println(" | + | |
| - | return "" | + | |
| - | } | + | |
| - | | + | |
| - | System.out.println(" | + | |
| } | } | ||
| finally { | finally { | ||
| - | | + | |
| - | try{ | + | |
| - | System.out.println(" | + | |
| - | fReader.close(); | + | |
| - | } | + | |
| - | catch(IOException ex) { | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | } | + | |
| - | else { | + | |
| - | System.out.println(" | + | |
| - | } | + | |
| - | | + | |
| } | } | ||
| - | return ""; | + | } |
| - | } | + | } |
| + | </ | ||
| + | |||
| + | ===== Try with resources block ===== | ||
| + | |||
| + | Η Java παρέχει τη δυνατότητα για αυτόματo κλείσιμο των αντικειμένων που οι κλάσεις τους υλοποιούν το interface [[https:// | ||
| + | |||
| + | Η κλάση [[https:// | ||
| + | |||
| + | <code java ExceptionHandling.java> | ||
| + | import java.util.Scanner; | ||
| + | import java.util.NoSuchElementException; | ||
| + | import java.util.InputMismatchException; | ||
| + | |||
| + | public class ExceptionHandling { | ||
| | | ||
| - | public static void main(String | + | public static void main(String []args) { |
| - | | + | |
| - | try { | + | try (Scanner sc = new java.util.Scanner(System.in)){ |
| - | System.out.println(wfr.readFile(args[0]) ); | + | System.out.print(" |
| - | } | + | int width = sc.nextInt(); |
| - | catch(IndexOutOfBoundsException | + | System.out.print(" |
| - | System.out.println(" | + | int height = sc.nextInt(); |
| + | double ratio = width / (double)height; | ||
| + | System.out.format(" | ||
| + | } catch(InputMismatchException ex) { | ||
| + | System.out.println(" | ||
| + | | ||
| + | System.out.println(" | ||
| } | } | ||
| } | } | ||
| - | |||
| } | } | ||
| </ | </ | ||
| - | Ο λόγος που συνήθως χρησιμοποιήσουμε το **finally** block είναι για να συμπεριλάβουμε κώδικα που θέλουμε να εκτελεστεί σε όλες τις περιπτώσεις, | + | Παρατηρήστε ότι τα αντικείμενα που θέλουμε να κλείσουν αυτόματα |
| - | + | ||
| - | Στο παραπάνω παράδειγμα δείτε την πορεία | + | |
| - | <code java> | + | |
| - | while ((inputLine = in.readLine()) != null) { | + | |
| - | strDocument.append(inputLine); | + | |
| - | //throw new IOException(); | + | |
| - | } | + | |
| - | </ | + | |
| - | |Προηγούμενο: | + | |Προηγούμενο: |