user414967
user414967

Reputation: 5325

java finalization doubts

I have some questions regarding java finalization. For example I have one class FileHelper and this class is associated with reading file,writing file,etc. Now my question is, I have one method writeFile() in FileHelper class.Now If I want to close that file should I override the finalize() method and close the file or can I close the file inside the writeFile() method itself? Which is the right way to do? I have declared my File variable as a member variable. If overriding is a bad idea, then why do we want to override finalize() method? which scenario? I have read many articles,where they are saying to close system resources such as file,font etc..

Upvotes: 0

Views: 139

Answers (4)

Stephen C
Stephen C

Reputation: 719376

Using finalizers is a bad idea, in nearly all circumstances. The Java specs state that there is no guarantee that finalizers will ever be run. And even if they do, you have no control over when this may happen.

Using finalizers as the primary mechanism to close files is always a bad idea. Why? Because if the GC doesn't run for a long time, your application is liable to run out of file descriptors, and file open attempts will start failing.

The best way to deal with opened streams is to keep them in local variables and parameters, and use try { ...} finally to make sure that they are always closed when you have finished with them. Or in Java 7, use the new "try with resource" syntax.

If you need to put the stream in a member variable, you probably should make the parent class implement a close() method that closes the streams, and use try { ...} finally to make sure that the instances of the parent class get closed.


It should also be noted that there is little point using a finalizer to close "lost" streams. The stream classes that use external resources that need to be closed already have finalizers to do this.

Upvotes: 1

Dhruv Arya
Dhruv Arya

Reputation: 105

The finalize() method would only get invoked when the Java Garbage Collector is about to reclaim the object. It is a bad practice to release file handle in the finalize method.

It may result in java.io.IOException: Too many open files as you cannot guarantee when the garbage collector would run.

A better option would be to close the file reader/writer object in the finally block. As it is guaranteed to run.

  finally {
  // Always close input and output streams. Doing this closes
  // the channels associated with them as well.
  try {
    if (fin != null)
      fin.close();
    if (fout != null)
      fout.close();
  } catch (IOException e) {
  }}

fin and fout are FileInputStream and FileOutputStream objects.

Upvotes: 1

Lukasz Madon
Lukasz Madon

Reputation: 15004

The best practice is to close the file as soon as possible. If you have static method in FileHelper (assuming that your Helper is a bunch of static "helper" methods) I would close the file inside

static void writeFile(String fileName, String text) { // Exception 
 // Open file here 
 // write text
 // close it
}

The purpose of overriding finalize is release the unmanaged resources e.g. files in case someone forget to do it. If someone use your helper this way

 FileHelper fileHelper = new FileHelper(file);
 fileHelper.writeFile(text);
 // forgot to fileHelper.close(); 

and you have overridden the finalize and call close() inside when GC runs the file will be closed. The problems:

  • As I mention earlier file should be closed as soon as possible (but not sooner ;) )
  • It's indeterministic (No body knows when GC will start)
  • This should be used only to prevent the case when the caller forgets to close the file

Upvotes: 3

Sunil
Sunil

Reputation: 1248

Overriding finalize() is not a good practice. I would have done it in the code.

Upvotes: 0

Related Questions