Java >> Java tutorial >  >> Java

Prøv-med-ressourcer-funktion i Java

Understøttelse af prøve-med-ressourcer, tilføjet i Java 7, giver os mulighed for at erklære, at ressourcer skal bruges i en prøveblok, mens vi ved, at de ville blive lukket, når de blev udført. Try-with-resources-sætningen i Java er en try-sætning med en eller flere ressourcer erklæret. Ressourcen er et objekt, der skal lukkes, når programmet er afsluttet. Try-with-resources-sætningen sikrer, at hver ressource lukkes ved afslutningen af ​​sætningsudførelsen.

De definerede ressourcer skal implementere den AutoCloseable-grænseflade.

Ethvert objekt, der implementerer java.lang, kan sendes. Derudover tages der hensyn til alle de objekter, der implementerer java.io.Closeable.

Ved brug af prøve-med-ressourcer-metoden

Enkelt sagt skal en ressource erklæres og initialiseres i forsøget på at blive automatisk lukket:

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Welcome to Codeunderscored");
}

Erstatning af try-catch-finally med try-with-ressources

Prøv-med-ressourcer er en teknik, der giver dig mulighed for at eksperimentere med forskellige ressourcer. Den nye prøve-med-ressourcer-funktionalitet erstatter den gamle og udførlige prøve-fang-endelig-blok i en gennemsigtig og ligetil tilgang.

Lad os tage et kig på nogle kodeeksempler.

Den første er et prøvet-og-sandt try-catch-endelig-mønster:

Scanner scan = null;
try {
    scan = new Scanner(new File("code.txt"));
    while (scan .hasNext()) {
        System.out.println(scan .nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if ( scan != null) {
        scan.close();
    }
}

Her er en ny, superkort løsning baseret på prøv-med-ressourcer:

try (Scanner scan = new Scanner(new File("code.txt"))) {
    while (scan .hasNext()) {
        System.out.println(scan .nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

prøv-med-ressourcer med en række ressourcer

Vi kan erklære flere ressourcer i en prøv-med-ressourcer-blok ved at bruge et semikolon til at adskille dem:

try (Scanner scan = new Scanner(new File("readCode.txt"));
    PrintWriter pWriter = new PrintWriter(new File("writeCode.txt"))) {
    while (scan scan ner.hasNext()) {
	pWriter.print(scan .nextLine());
    }
}

En brugerdefineret ressource, der kan lukkes automatisk

Klassen skal implementere de Lukbare eller AutoCloseable grænseflader og tilsidesætte lukkefunktionen for at skabe en brugerdefineret ressource, der vil blive håndteret korrekt af en prøv-med-ressourcer-blok:

public class CodeResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Code Resource Closed");
    }
}

Lukning af ressourceordre

De første definerede/erhvervede ressourcer lukkes sidst. Overvej følgende eksempel på denne type adfærd:

1. ressource:

public class CodeAutoCloseableResourcesInitial implementerer AutoCloseable {

public class CodeAutoCloseableResourcesInitial implements AutoCloseable {

    public CodeAutoCloseableResourcesInitial() {
        System.out.println("Constructor -> AutoCloseableResources_Initial");
    }

    public void exploreCode() {
        System.out.println("Something -> AutoCloseableResources_Initial");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_Initial");
    }
}

2. ressource

public class CodeAutoCloseableResourcesLast implements AutoCloseable {

    public CodeAutoCloseableResourcesLast() {
        System.out.println("Constructor -> AutoCloseableResources_Last");
    }

    public void exploreCode() {
        System.out.println("Explore -> AutoCloseableResources_Last");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_Last");
    }
}

private void CodeOrderOfClosingResources() throws Exception {
    try (CodeAutoCloseableResourcesFirst firstCode = new CodeAutoCloseableResourcesFirst();
        CodeAutoCloseableResourcesSecond lastCode = new CodeAutoCloseableResourcesLast()) {

        firstCode.exploreCode();
        lastCode.exploreCode();
    }
}

Fang og til sidst

Fangsten og endelig blokkene bruges stadig i en prøv-med-ressourcer-blok, og de vil fungere på samme måde, som de ville i en standard prøveblok.

Faktisk endelige variabler i Java 9

Vi kunne kun bruge friske variabler i en prøv-med-ressourcer-blok før Java 9:

try (Scanner scan = new Scanner(new File("readCode.txt"));
    PrintWriter pWriter = new PrintWriter(new File("writeCode.txt"))) {
    // omitted
}

Det var især omfattende, når man definerede talrige ressourcer, som vist ovenfor. Vi kan nu bruge endelige eller i det væsentlige endelige variabler i en prøv-med-ressourcer-blok fra Java 9 og som en del af JEP 213:

final Scanner scan = new Scanner(new File("readCode.txt"));
PrintWriter pWriter = new PrintWriter(new File("writeCode.txt"))
try (scan;pWriter) {
    // omitted
}

Selvom en variabel ikke udtrykkeligt er markeret som endelig, er den i det væsentlige endelig, hvis den ikke ændres efter den første opgave.

Scanningsvariablen er eksplicit erklæret endelig, som vist ovenfor, for at bruge den med prøve-med-ressourcer-blokken. Writer-variablen ændres ikke efter den første opgave, selvom den ikke er eksplicit endelig. Som et resultat kan vi også bruge variablen pWriter. Som følge heraf behøver vi ikke længere at inkludere en ekstra endelig blok for blot at videresende ressourcernes lukkeerklæringer. Ressourcerne vil blive lukket, så snart try-catch-blokken er udført.

Prøv-med-ressourcer syntaks :

try(declare resources here) {
    // use resources
}
catch(FileNotFoundException e) {
    // exception handling
}

eller

try (resource declaration) {
  // use of the resource
} catch (ExceptionType e1) {
  // catch block
}

Som det kan ses af syntaksen ovenfor, erklæres try-with-resources-sætningen ved, inden for try-sætningen, at erklære og instansiere ressourcen. Alle undtagelser, der kan kastes, mens ressourcen lukkes, er specificeret og håndteret. Det er værd at bemærke, at try-with-ressources-erklæringen lukker alle ressourcer, der implementerer den AutoCloseable-grænseflade.

Undtagelser

Der er en sondring mellem prøve-fangst-endelig og prøve-med-ressourcer-blokkene for undtagelser. Metoden returnerer den undtagelse, der er smidt i finally-blokken, hvis en undtagelse kastes i både forsøg og endelig blokke.

Hvis en undtagelse kastes i både en try-blok og en try-with-resources-sætning i try-with-resources, returnerer metoden den undtagelse, der er kastet i try-blokken. Undtagelserne prøv med ressourcer er undertrykt. Således kan vi sige, at prøve-med-ressourcer-blokken kaster undertrykte undtagelser.

Lad os nu tage et kig på begge alternative omstændigheder, hvoraf den ene er vist nedenfor som et eksempel:

  • Case 1:En enkelt informationskilde
  • Case 2:En række ressourcer

Eksemplet nedenfor gemmer en streng til en fil. Den skriver data til filen ved hjælp af et FileOutputStream-objekt. Ressourcen FileOutputStream skal lukkes, når programmet har brugt den. Som et resultat, i dette eksempel, forsøges ressourcelukning af sig selv.

import java.io.FileOutputStream;   

 
public class CodeTryWithResources {
    
public static void main(String args[]){      
 
// Using try-with-resources  
try(FileOutputStream fileOutputStream =newFileOutputStream("/java7-new-features/src/abc.txt")){      
String msgString = "Welcome to Codeunderscored!";      
byte byteArray[] = msgString.getBytes(); //converting string into byte array      
fileOutputStream.write(byteArray);  
System.out.println("Message is successfuly written to file!");   
   
}catch(Exception exception){  
       System.out.println(exception);  
}      
}      
}  

Prøv-med-ressourcer Eksempel:Brug af flere ressourcer

  import java.io.DataInputStream;  
    import java.io.FileInputStream;  
    import java.io.FileOutputStream;  
    import java.io.InputStream;    

    public class CodeTryWithResources {    
    public static void main(String args[]){      
    
// Using try-with-resources  
    try(    // Using multiple resources  
            FileOutputStream fileOutputStream =new FileOutputStream("/java7-new-features/src/abc.txt");  
            InputStream input = new FileInputStream("/java7-new-features/src/abc.txt")){  

            // -----------------------------Code to write data into file--------------------------------------------//  
            String msgString = "Welcome to Codeunderscored!";      
            byte byteArray[] = msgString.getBytes();  // Converting string into byte array      
            fileOutputStream.write(byteArray);  // Writing  data into file  
            System.out.println("------------ Writing data to file--------------");  
            System.out.println(msgString);  


            // -----------------------------Code for reading data from file---------------------------------------//  
           
	// Creating input stream instance  
            DataInputStream inputStream = new DataInputStream(input);    
            int data = input.available();    
            // Returns an estimate of the number of bytes that can be read from this input stream.   
            byte[] bArray = new byte[data]; //    
            inputStream.read(bArray);    
            String str = new String(bArray); // passing byte array into String constructor
 
            System.out.println("------------Data after reading from the file--------------");  
            System.out.println(str); // display file data

    }catch(Exception exception){  
           System.out.println(exception);  
    }     
    }      
    }   

Med en try-with-ressources-erklæring kan du bruge catch og endelig blokeringer på samme måde med en almindelig try-erklæring. Fang, eller endelig, bloker eksekveringer, efter at de angivne ressourcer er lukket i en try-with-resources-sætning.

Prøv-med-ressourcer Eksempel:Brug endelig blok

 import java.io.FileOutputStream;    


    public class CodeTryWithResources {    

    public static void main(String args[]){      
    try(    FileOutputStream outputStream=  
      new FileOutputStream("/home/tuts/code/java7-new-features/src/abc.txt")){  

        // -----------------------------Code for writing data into file--------------------------------------------//  

            String msgString = "Welcome to Codeunderscored!";      
            byte bArray[] = msgString.getBytes();  // Conversion of a string into byte array      
            outputStream.write(bArray);  // process of writing  data into file  
            System.out.println("Data writing completed successfully!");  

    }catch(Exception exception){  
           System.out.println(exception);  
    }  
    finally{  
           System.out.println(" Executes finally after closure of declared resources.");  
    }  
    }      
    }  

Eksempel:prøv-med-ressourcer

import java.io.*;

class Codeunderscored {
  public static void main(String[] args) {
    String line_text;
    try(BufferedReader bReader = new BufferedReader(new FileReader("code.txt"))) {
      while (( line_text = bReader.readLine()) != null) {
        System.out.println("Line =>"+line_text);
      }
    } catch (IOException e) {
      System.out.println("IOException in try block =>" + e.getMessage());
    }
  }
}

Vi bruger en BufferedReader-instans til at læse data fra code.txt-filen i dette eksempel. Brug af try-with-resources-sætningen til at erklære og instansiere BufferedReader sikrer, at dens instans lukkes, uanset om try-sætningen lykkes eller mislykkes. Hvis der opstår en undtagelse, bruges undtagelseshåndteringsblokkene eller throws nøgleordet til at administrere det.

Undtagelser, der er blevet undertrykt

Undtagelser kan kastes fra try-with-resources-sætningen i eksemplet ovenfor, når:

  • Filen test.txt kunne ikke findes.
  • BufferedReader-objektet lukkes.

Fordi en fillæsning kan mislykkes af forskellige årsager til enhver tid, kan der kastes en undtagelse fra prøveblokken. Hvis både try-blokken og try-with-resources-sætningen afgiver undtagelser, kastes try-blok-undtagelsen, og try-with-resources-sætningen er skjult.

Hvis en prøve-blok kaster en undtagelse, og prøv-med-ressourcer kaster en eller flere undtagelser, bliver prøve-med-ressourcerne-undtagelserne dæmpet. Undtagelser kastet af prøv-med-ressourcer er undertrykte undtagelser, for at sige det på en anden måde.

Hentning af undtagelser, der er blevet undertrykt

De undertrykte undtagelser kan fås i Java 7 og senere ved at påberåbe Throwable.getSuppressed() metoden. Prøv-blokkens undtagelse videregives til processen.

Denne metode returnerer en række af alle undtagelser, der er blevet undertrykt. I catch-blokken får vi de undertrykte undtagelser.

catch(IOException e) {
  System.out.println("The Exception Thrown=>" + e.getMessage());
  Throwable[] sExceptions = e.getSuppressed();
  for (int i=0; i<sExceptions.length; i++) {
    System.out.println("Exceptions Suppressed=>" + sExceptions[i]);
  }
}

GetSuppress()-funktionen i Throwable-klassen bruges til at opnå disse undtagelser. Java leverede en ny konstruktør og to nye metoder til Throwable-klassen for at klare undertrykte undtagelser.

Konstruktør

protected Throwable(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)

Det opretter en ny smidbar med den medfølgende detaljemeddelelse, årsag, undertrykkelse, hvad enten den er aktiveret eller deaktiveret, og skrivbar staksporing, som enten kan aktiveres eller deaktiveres.

Metode

public final void addSuppressed(Throwable exception)/td&gt;

For at formidle denne undtagelse tilføjer den den angivne undtagelse til de undertrykte undtagelser. Try-with-resources-sætningen kalder typisk denne trådsikker procedure (automatisk og implicit). Følgende undtagelser er kastet:
IllegalArgumentException:En throwable kan ikke undertrykke sig selv, hvis undtagelsen er throwable. Hvis undtagelsen er null, kastes en NullPointerException.

public final Throwable[] getSuppressed()

Det producerer et array med alle de undtagelser, som kommandoen try-with-resources undertrykte. Et tomt array returneres, hvis ingen undtagelser er undertrykt, eller hvis undertrykkelse er deaktiveret.

Eksempel:Program til at prøve-med-ressourcer med en enkelt ressource

// Importing all input output classes
import java.io.*;

// Class
class Codeunderscored {

	// Main driver method
	public static void main(String[] args)
	{
		// Try block to check for exceptions
		try (

			// Creating an object of FileOutputStream
			// to write stream or raw data

			// Adding resource
			FileOutputStream fos
			= new FileOutputStream("gfgtextfile.txt")) {

			// Custom string input
			String text
				= "Hello World. This is my java program";

			// Converting string to bytes
			byte arr[] = text.getBytes();

			// Text written in the file
			fos.write(arr);
		}

		// Catch block to handle exceptions
		catch (Exception e) {

			// Display message for the occured exception
			System.out.println(e);
		}

		// Display message for successful execution of
		// program
		System.out.println("Resource are closed and message has been written into the code.txt");
	}
}

Ressourcen er lukket, og en besked er blevet skrevet ind i code.txt

Eksempel:Program til at prøve-med-ressourcer med flere ressourcer

// Importing all input output classes
import java.io.*;

// Class
class Codeunderscored {

	// Main driver method
	public static void main(String[] args)
	{
		// Try block to check for exceptions

		// Writing data to a file using FileOutputStream
		// by passing input file as a parameter
		try (FileOutputStream outputStream
			= new FileOutputStream("outputfile.txt");

			// Adding resouce

			// Reading the stream of character from
			BufferedReader br = new BufferedReader(
				new FileReader("code.txt"))) {

			// Declaring a string holding the
			// stream content of the file
			String text;

			// Condition check using readLine() method
			// which holds true till there is content
			// in the input file
			while ((text = br.readLine()) != null) {

				// Reading from input file passed above
				// using getBytes() method
				byte arr[] = text.getBytes();

				// String converted to bytes
				outputStream.write(arr);

				// Copying the content of passed input file
				// 'inputgfgtext' file to code.txt
			}

			// Display message when
			// file is successfully copied
			System.out.println(
				"File content copied to another one.");
		}

		// Catch block to handle generic exceptions
		catch (Exception e) {

			// Display the exception on the
			// console window
			System.out.println(e);
		}

		// Display message for successful execution of the
		// program
		System.out.println("Resource are closed and message has been written into the code.txt");
	}
}

Indholdet af en fil kopieres til en anden. Yderligere er ressourcen blevet lukket, og meddelelsen er blevet gemt i filen code.txt.

Forbedring af Java 9s prøve-med-ressourcer-metode

Try-with-resources-sætningen har en begrænsning i Java 7. Inden for dens blok skal du erklære ressourcen lokalt.

try (Scanner scan= new Scanner(new File("readCode.txt"))) {
  // code
}

I Java 7 ville erklæring af ressourcen uden for blokken have resulteret i en fejlmeddelelse.

Scanner scan = new Scanner(new File("readCode.txt"));
try (scan) {
  // code
}

Java 9 opdaterede try-with-resources-erklæringen for at løse dette problem for at tillade, at ressourcens reference kan bruges, selvom ressourcen ikke er angivet lokalt. Uden nogen kompileringsfejl vil koden ovenfor nu køre.

Konklusion

I denne artikel undersøgte vi, hvordan man bruger prøv-med-ressourcer, og hvordan man erstatter prøv, fang og endelig med prøv-med-ressourcer. Vi så også på at bruge AutoCloseable til at oprette brugerdefinerede ressourcer og den rækkefølge, de lukkes i.

Try-with-resources-sætningen i Java er en try-sætning med en eller flere ressourcer erklæret. Når dit program er færdig med at bruge det, skal du lukke ressourcen. En filressource, for eksempel, eller en socketforbindelsesressource. Prøv-med-ressourcer-sætningen sikrer, at hver ressource er lukket i slutningen af ​​sætningsudførelsen. Hvis vi ikke lukker ressourcerne, kan det resultere i et ressourcelæk, og programmet kan udtømme sine ressourcer.

Ethvert objekt, der implementerer java.lang, kan sendes som en ressource. Også alle objekter, der implementerer java.io.Closeable, betragtes som AutoCloseable.


Java tag