Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is mandatory to use "throws IOException"

Why it is mandatory to use "throws IOException" in main method while handling an external file operation, if the file is located within the local file system.

like image 471
Mayur Patel Avatar asked Feb 25 '12 04:02

Mayur Patel


3 Answers

It may not be mandatory to add the throws IOException to your main function, but its mandatory to do something about the exception. When you're doing file io, or network io, or other (?) io, something could go wrong. The file might not exist, it could be on a bad sector of the disk, the network could crash halfway through (which could matter for network or file io if the disk is not a local disk).

The reason that you need to do something about the IOException is that it is a checked exception. If you call a constructor or a function that throws a checked exception then you either need to handle it, by catching it and taking appropriate actions. Or you need to tell the compiler that you know about the exception, but you don't plan to do anything about it, in which case you must declare throws IOException in your function definition.

There is another type of exception, unchecked exceptions (sometimes called runtime exceptions because they all extend RuntimeException). Unchecked exceptions were supposed to be potential runtime problems. e.g. NullPointerException (NPE), an example of an NPE that is due to runtime conditions is when something that you expect to return an object returns a NULL, and then you try to invoke a method on that. That's the theory at least.

So you might be thinking, well, runtime exceptions are for unanticipated runtime problems, then why the heck isn't an IOException a runtime exception! Its not like I planned for the fraking disk to fail, or for a backhoe operator in Schenectady to take out half the coast. For crying out loud I'd like to know that too! Somebody give me a Hallelujah, Oh I hear ya!

I have done a ton of IO related work in Java and typing throws IOException is sort of like this eyesore that I have just learned to live with, because in general, it's a bad idea to try to handle IOExceptions at a low level, because low level code has no idea at all what the context is of what you're trying to do, and it should let those exceptions bubble up to to code where there is context on what you're trying to accomplish.

Oh, and BTW, I mentioned that I'd like to know why an IOException isn't a runtime exception whereas something like a NPE is? Yes it's a runtime condition, but IO (disk, network, whatever) is a lot less reliable than you might think. If you're convinced that disk is reliable, go read about some of the reasons why Sun invented ZFS. And if you think that network is reliable, try making sure that you've got marketing content reliably downloaded to 15,000 crappy Windows based kiosks over lousy 3d party networks and make sure that a customer never sees a junk image that was broken due to a network problem. (Can you say sha-1 hash sum children? I knew you could).

I am going somewhere with this; I promise.

I think the reason that IOException is a checked exception is that IO is not reliable (Go look at fallacy #1 of the Fallacies of Distributed Computing.) In general, you should be able to get the NPE bugs out of your code, but IO is a different beast, it's not reliable, and I think their intent was to force you to think about it. Did I mention that one of the authors of the Fallacies of Distributed Computing is James Gosling. James Gosling, the very same person credited as the father of Java? Yeah, that's my theory at least. Either that or it was all just a huge stupid mistake. There's a lot of that in the early Java libraries.

There's been lots of debate about the usefulness of checked exceptions, and over time I've come to agree with the people who say that they're just not worth the effort, and if there are cases where there are a lot of annoying pointless checked exceptions being declared, I will wrap them and rethrow an appropriate runtime Exception (say hello to my lil friend!). Despite this, I do not mess with IOException; the wise thing to do is live with the pain.

Oh, and for simple, does one thing code all fits in the public static void main(String[]) throws IOException function? The right answer is to probably just let the exception bubble out and let the runtime report it to the poor guy who is trying to run your code.

Thanks, good night.

like image 79
Bill Avatar answered Oct 12 '22 13:10

Bill


It is not at all mandatory to use throws IOException. If you call a method that can throw an exception, though, you're required to either

  1. Catch it, or
  2. Declare that you're going to rethrow it.

The second one is what you're doing. The other one -- which is often the preferred technique -- is to catch and handle the exception yourself:

public static void main(String[] argv) {
    try {
        FileReader f = new FileReader("foo.txt");
        // ... more
    } catch (IOException ioe) {
        System.out.println("Trouble reading from the file: " + ioe.getMessage());
    } 
}
like image 32
Ernest Friedman-Hill Avatar answered Oct 12 '22 13:10

Ernest Friedman-Hill


AFAIK, it is not mandatory.

You either handle the exception or you don't.

If you do handle the exception, then you need to put a try {...} catch(IOException e) {...}, but if you don't handle it, just declare the throws IOException in the current method.

like image 35
Gabriel Belingueres Avatar answered Oct 12 '22 13:10

Gabriel Belingueres