views:

304

answers:

5

I can "fix" the below exception with a try-catch loop but I cannot understand the reason.

  1. Why does the part "in.readLine()" continuosly ignite IOExceptions?
  2. What is really the purpose of throwing such exceptions, the goal probably not just more side effects?

Code and IOExceptions

$ javac ReadLineTest.java 
ReadLineTest.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown
  while((s=in.readLine())!=null){
                      ^
1 error
$ cat ReadLineTest.java 
import java.io.*;
import java.util.*;

public class ReadLineTest {
 public static void main(String[] args) {
  String s;
  BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  // WHY IOException here?
  while((s=in.readLine())!=null){
   System.out.println(s);
  }
 }
}
+1  A: 

IOException is a checked exception. You must either catch it, or throw it to your calling method. Checked exceptions are caused by external actors, like a missing file, failed disk or anything that you cannot recover from in your program code.

However an Unchecked exception like ArrayIndexOutofBoundsException is caused by faulty logic in the program. You can subvert it by using an if condition outside your defective code (something like if currIndex>array.length). There is no such provision in case of checked exception

Midhat
+1  A: 

It is thrown if an exceptional situation occurs with the I/O, for example the source of the stream is no longer available.

In such cases your program should be able to recover. Either by re-reading the source, or by using some defaults, or by alerting the user about the problem.

You are forced to catch it, because it is a checked exception, and you are supposed to be able to recover from those.

Of course, you have the option to declare that the current menthod throws this exception to caller methods, but you will have to catch it eventually (or let it bubble up to the main method, when it is simply printed on the console and the program execution stops)

Bozho
@downvoter - let me fix what you think is wrong with this answer.
Bozho
A: 

BufferedReader.readLine() is declared as potentially throwing an exception, see: http://java.sun.com/j2se/1.3/docs/api/java/io/BufferedReader.html#readLine()

You either need to catch it, or declare your main method as throwing IOException.

Ie, either do this:

try {
    while((s=in.readLine()) != null){
        System.out.println(s);
     }
} catch(IOException e) {
    // Code to handle the exception.
}

Or

public static void main(String[] args) throws IOException { ...
Tom
+2  A: 
  1. It won't "continously ignite" them, it just might throw them each time you invoke it. In your case, if it throws something it means something has gone badly wrong with your standard input.
  2. The goal is to ensure that you, the programmer using the API, deals with the problem, since it is in general assumed to be a recoverable problem - although in your particular case it will be fatal for your whole program.
jjujuma
+2  A: 

The basic idea is that a BufferedReader delegates to a different kind of Reader, so it is passing on that exception.

That different kind of Reader can read from some kind of volatile external resource, say a file system in the case of FileReader. A file system read can fail for many reasons at any time. (The situation is worse if the Reader is getting its underlying data from a Network Stream). The file could get deleted out from under you (depending on the file system and OS involved).

Because you cannot predict what will happen with code, you get a checked exception - the point being that the API is telling you that you should think about the fact that this operation may not work out even if there is nothing wrong with your code.

Yishai