Σε αυτό το σεμινάριο, θα μάθουμε για τη δήλωση δοκιμής με πόρους για να κλείσουμε αυτόματα τους πόρους.
Η try-with-resourcesδήλωση κλείνει αυτόματα όλους τους πόρους στο τέλος της δήλωσης. Ένας πόρος είναι ένα αντικείμενο που πρέπει να κλείσει στο τέλος του προγράμματος.
Η σύνταξή του είναι:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Όπως φαίνεται από την παραπάνω σύνταξη, δηλώνουμε τη try-with-resourcesδήλωση από,
- δηλώνει και τεκμηριώνει τον πόρο εντός της
tryρήτρας. - καθορίζοντας και χειρίζοντας όλες τις εξαιρέσεις που ενδέχεται να απορριφθούν κατά το κλείσιμο του πόρου.
Σημείωση: Η δήλωση δοκιμής με πόρους κλείνει όλους τους πόρους που εφαρμόζουν τη διεπαφή AutoCloseable.
Ας πάρουμε ένα παράδειγμα που εφαρμόζει τη try-with-resourcesδήλωση.
Παράδειγμα 1: δοκιμάστε με πόρους
import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) )
Έξοδος εάν το αρχείο test.txt δεν βρεθεί.
IOException στο try-with-resources block => test.txt (Δεν υπάρχει τέτοιο αρχείο ή κατάλογος)
Έξοδος αν βρεθεί το αρχείο test.txt.
Εισαγωγή της γραμμής δοκιμής με πόρους block => test line
Σε αυτό το παράδειγμα, χρησιμοποιούμε μια παρουσία του BufferedReader για να διαβάσουμε δεδομένα από το test.txtαρχείο.
Η δήλωση και η παρουσίαση του BufferedReader μέσα στη try-with-resourcesδήλωση διασφαλίζει ότι η παρουσία της είναι κλειστή ανεξάρτητα από το αν η tryδήλωση ολοκληρώνεται κανονικά ή ρίχνει μια εξαίρεση.
Εάν προκύψει εξαίρεση, μπορεί να αντιμετωπιστεί χρησιμοποιώντας τα μπλοκ χειρισμού εξαιρέσεων ή τη λέξη-κλειδί ρίψεων.
Καταπιεσμένες εξαιρέσεις
Στο παραπάνω παράδειγμα, εξαιρέσεις μπορούν να απορριφθούν από τη try-with-resourcesδήλωση όταν:
- Το αρχείο
test.txtδεν βρέθηκε. - Κλείσιμο του
BufferedReaderαντικειμένου.
Μια εξαίρεση μπορεί επίσης να απορριφθεί από το tryμπλοκ καθώς η ανάγνωση ενός αρχείου μπορεί να αποτύχει για πολλούς λόγους ανά πάσα στιγμή.
Εάν ρίχνονται εξαιρέσεις τόσο από το tryμπλοκ όσο και από τη try-with-resourcesδήλωση, η εξαίρεση από το tryμπλοκ ρίχνεται και η εξαίρεση από τη try-with-resourcesδήλωση καταργείται.
Ανάκτηση κατασταλμένων εξαιρέσεων
Στην Java 7 και μεταγενέστερες εκδόσεις, οι κατασταλμένες εξαιρέσεις μπορούν να ανακτηθούν καλώντας τη Throwable.getSuppressed()μέθοδο από την εξαίρεση που ρίχνεται από το tryμπλοκ.
Αυτή η μέθοδος επιστρέφει έναν πίνακα όλων των εξαιρούμενων εξαιρέσεων. Παίρνουμε τις κατασταλμένες εξαιρέσεις στο catchμπλοκ.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Πλεονεκτήματα της χρήσης δοκιμαστικών πόρων
Ακολουθούν τα πλεονεκτήματα της χρήσης του try-with-resources:
1. επιτέλους μπλοκ δεν απαιτείται για να κλείσετε τον πόρο
Πριν από την εισαγωγή του Java 7 σε αυτήν τη δυνατότητα, έπρεπε να χρησιμοποιήσουμε το finallyμπλοκ για να διασφαλίσουμε ότι ο πόρος είναι κλειστός για να αποφευχθούν διαρροές πόρων.
Ακολουθεί ένα πρόγραμμα παρόμοιο με το Παράδειγμα 1 . Ωστόσο, σε αυτό το πρόγραμμα, χρησιμοποιήσαμε επιτέλους μπλοκ για κλείσιμο πόρων.
Παράδειγμα 2: Κλείσιμο πόρου χρησιμοποιώντας τελικά μπλοκ
import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) )
Παραγωγή
Είσοδος try block Line => line from test.txt file Είσοδος τελικά block
Όπως μπορούμε να δούμε από το παραπάνω παράδειγμα, η χρήση του finallyμπλοκ για την εκκαθάριση πόρων καθιστά τον κώδικα πιο περίπλοκο.
Παρατηρήστε επίσης το try… catchμπλοκ στο finallyμπλοκ; Αυτό συμβαίνει επειδή IOExceptionμπορεί επίσης να προκύψει κατά το κλείσιμο της BufferedReaderπαρουσίας μέσα σε αυτό το finallyμπλοκ, ώστε να πιάσει και να χειριστεί επίσης.
Η try-with-resourcesδήλωση κάνει αυτόματη διαχείριση πόρων . Δεν χρειάζεται να κλείσουμε ρητά τους πόρους καθώς η JVM τους κλείνει αυτόματα. Αυτό κάνει τον κώδικα πιο ευανάγνωστο και ευκολότερο να γραφτεί.
2. δοκιμάστε με πόρους με πολλούς πόρους
Μπορούμε να δηλώσουμε περισσότερους από έναν πόρους στη try-with-resourcesδήλωση διαχωρίζοντάς τους με ερωτηματικό;
Παράδειγμα 3: δοκιμάστε με πολλούς πόρους
import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) )
Εάν αυτό το πρόγραμμα εκτελείται χωρίς να δημιουργηθούν εξαιρέσεις, το Scannerαντικείμενο διαβάζει μια γραμμή από το testRead.txtαρχείο και το γράφει σε ένα νέο testWrite.txtαρχείο.
Όταν γίνονται πολλές δηλώσεις, η try-with-resourcesδήλωση κλείνει αυτούς τους πόρους με αντίστροφη σειρά. Σε αυτό το παράδειγμα, το PrintWriterαντικείμενο κλείνει πρώτα και μετά το Scannerαντικείμενο είναι κλειστό.
Βελτίωση δοκιμών με πόρους Java 9
Στην Java 7, υπάρχει ένας περιορισμός στη try-with-resourcesδήλωση. Ο πόρος πρέπει να δηλωθεί τοπικά εντός του μπλοκ του.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Εάν δηλώσαμε τον πόρο εκτός του μπλοκ στην Java 7, θα δημιουργούσε ένα μήνυμα σφάλματος.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Για να αντιμετωπίσει αυτό το σφάλμα, η Java 9 βελτίωσε τη try-with-resourcesδήλωση, έτσι ώστε η αναφορά του πόρου να μπορεί να χρησιμοποιηθεί ακόμη και αν δεν δηλώνεται τοπικά. Ο παραπάνω κώδικας θα εκτελεστεί χωρίς κανένα σφάλμα σύνταξης.








