-1

I'm currently doing something like this in java to free resources. Do I need to call close on the BufferedWriter object or is it called in the destructor? With regard to Resource1 and Resource2, I must call release and free respectfully. Is this the correct approach with nested trys? Python has a really nice "with statement" which associates resources with a code scope. Does java have the likes?

Resource1 r1 = new Resource1();
try
{
    ...
    Resource2 r1 = new Resource2();
    try
    {
        ...
        java.io.BufferedWriter f = new java.io.BufferedWriter(new java.io.FileWriter(new java.io.File("f")));
        try
        {
           ...
        }
        finally
        {
           f.close(); 
        }
    }
    finally
    {
        r2.release(); 
    }
}
finally
{
    r1.free(); 
}

UPDATE: I'm using Java 1.6

Baz
  • 12,713
  • 38
  • 145
  • 268
  • 1
    Java 7 has try with resource feature, from your question not clear which java version you are using http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html – kosa Dec 07 '12 at 15:37
  • possible duplicate of [How to Correctly Close Resources](http://stackoverflow.com/questions/5782647/how-to-correctly-close-resources) – djechlin Dec 07 '12 at 15:38
  • @djechlin I have googled... – Baz Dec 07 '12 at 15:48
  • @Baz I copied and pasted the title of your question into Google and the first hit was the link I voted to close as duplicate. – djechlin Dec 07 '12 at 15:51
  • @djechlin That post is very confusing. In two examples, exceptions are swallowed. And two other comments/examples mention that you should never ever swallow an exception. Which is correct? Which example in that post would you go with for Java 1.6? – Baz Dec 07 '12 at 16:01
  • Those questions should be part of this post to make it a more specific and meaningful question - you will notice your answers right now are the exact same as the ones in that thread, which reflects the fact that you posted a duplicated question. – djechlin Dec 07 '12 at 16:07

2 Answers2

3

What you have with respect to BufferedWriter is correct.

However, you may want to swallow any exceptions that occur during close. This is annoying but necessary. Often the following pattern is used:

BufferedWriter f = null;
try {
  f = new BufferedWriter(...);
  ...
}
finally {
  try {
    if(f != null) {
      f.close();
    }
  }
  catch(IOException e) {
    // Nothing can be done, except maybe log it.
  }
}

IOUtils.finallyClose() can be used to remove the need for the catch on close.

Java doesn't quite have the concept of destructors, but it does have finalize() that get's call when an object is garbage collected. You should never depend on finialize() to close or otherwise cleanup an object.

Btw, Java 7 introduced a shorter syntax for closing objects that implement Closeable.

try (BufferedWriter f = new BufferedWriter(new FileWriter(new File("f"))) {
  ...
}

EDIT: I expanded on finally..close.

Community
  • 1
  • 1
mikeslattery
  • 4,039
  • 1
  • 19
  • 14
  • I'm new to Java but I've never swallowed exceptions before. Must I really do this? Isn't f guaranteed to be an instance after the line java.io.BufferedWriter f = ...? – Baz Dec 07 '12 at 15:51
  • 1
    Yes (unless you're using the new Java 7 syntax). Some have criticized Sun for making close throw a checked exception. I guess it's good to know something went wrong during the close, but in many situations there's nothing you can do about it by that time. In just about every other case, it's a bad idea to swallow exceptions. I highly suggest using Java 7 for this kind of thing, if that's an option for you. – mikeslattery Dec 07 '12 at 16:07
2

You need to close the file handle and other similar resoures yourself. It is a bad approach to rely on the finalizer to do this.

Audrius Meškauskas
  • 20,936
  • 12
  • 75
  • 93
  • finally block is meant to close your resources, i dont understand your answer – PermGenError Dec 07 '12 at 15:40
  • i am not the OP , :P, i dont understand what you mean by `finalizer` in your code ? – PermGenError Dec 07 '12 at 15:43
  • Finalizer is an object method called by JRE when the object is garbage collected. Every object has such, it is normally overridden to free all attached resources. However with more memory available you may get out of handles before the garbage is collected. – Audrius Meškauskas Dec 07 '12 at 15:45
  • ahh, you meant finalize() method in object class.. haha, i tought you were refering to finally block in which case yoour answer would be incorrect, anyways, thats a right answer, +1 – PermGenError Dec 07 '12 at 15:48