Java try with resources enhancements

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

  1. With Java 7, Java introduced try-with-resource feature that helps to close resource automatically after being used.

    In other words, we don’t need to close resources (file, connection, network etc) explicitly, try-with-resource close that automatically by using AutoClosable interface.

    In Java 7, try-with-resources has a limitation that requires resource to declare locally within its block.

    In Java 7, the try-with-resources syntax requires a fresh variable to be declared for each resource being managed by the statement.

    try(FileOutputStream fileStream=new FileOutputStream("javatpoint.txt");){
        String greeting = "Welcome to javaTpoint.";
        byte b[] = greeting.getBytes();
        fileStream.write(b);
        System.out.println("File written");
    }catch(Exception e) {
        System.out.println(e);
    }
    
  2. In Java 9

    1. In Java 9, a new enhancement is made which allows developers to declare resources outside the try-with-resources block. There is no need to declare another variable inside try-with-resources block to access the resource.

      Java wants you to ensure that the variable you pass to try-with-resources (in this case fileStream, reader, writer) will not be changed once it is assigned. If the variable could be changed (say within the try block itself) then all sorts of undefined behaviour might arise.

      FileOutputStream fileStream = new FileOutputStream("javatpoint.txt");
      BufferedReader reader = new BufferedReader(new FileReader(new File("myfile.txt")));
      BufferedWriter writer = new BufferedWriter(new FileWriter(new File("myfile.txt")));
      try(fileStream; reader; writer) {
          String greeting = "Welcome to javaTpoint.";
          byte b[] = greeting.getBytes();
          fileStream.write(b);
          System.out.println("File written");
      
          while (nonNull(line = reader.readLine())) {
              writer.write(line);
          }
      }catch(Exception e) {
          System.out.println(e);
      }
      
    2. There is an additional refinement: if the resource is referenced by a final or effectively final variable, a try-with-resources statement can manage a resource without a new variable being declared:

      try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
          // do some stuff with finalCloseable
      } catch (Exception ex) { }
      

Should Class.getResourceAsStream() be closed?

https://stackoverflow.com/questions/19598088/should-class-getresourceasstream-be-closed

I was wondering if this is required since when I use this method, the file is being read from the classpath. Does “not closing” it lead to a memory leak.

Answer:

You are assuming that Class.getResourceAsStream() will always return a stream that points to a file inside your class’ JAR file. This is incorrect. Your classpath may also contains folders, in which case Class.getResourceAsStream() will return a FileInputStream. Some other class loaders might also return other type of resources, such as remote files (in the case of a URLClassLoader).

Even in the case of a JAR file, it is possible that the implementation maintain, by whatever mean, a persistant view inside the JAR file to the compressed bytes of the file you are accessing. Maybe it is holding upon a memory mapped ~ByteBuffer…

Why take the chance? You should always close streams (and any other Closeable, actually), no matter how they were given to you.

Note that since Java 7, the preferred method to handle closing any resource is definitely the try-with-resources construct. It correctly handles several corner cases that are very hard to manage in hand written code, and yet it is almost as easy to write for you as if you had simply forgot about closing the resource. For example, you may use code like this:

The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.


try (InputStream in = Class.getResourceAsStream("someresource.txt")) {
    // Use the stream as you need to...
}

// Then forget about it... and yet, it has been closed properly.

Links to this note