Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 529


Previous 1060 Stories (530 Pages, 2 Per Page) Next

Exceptions -III: What's an exception and why do I care?

Go to all tips in Java Lectures by Anatoliy Malyarenko

Java's catch or specify requirement

Part I was published here, Part II was published here.

As stated previously, Java requires that a method either catch or specify all checked exceptions that can be thrown within the scope of the method. This requirement has several components that need further description: "catch", "specify," "checked exceptions," and "exceptions that can be thrown within the scope of the method."


Catch: a method can catch an exception by providing an exception handler for that type of exception.

Specify: if a method chooses not to catch an exception, the method must specify that it can throw that exception. Why did the Java designers make this requirement? Because any exception that can be thrown by a method is really part of the method's public programming interface: callers of a method must know about the exceptions that a method can throw in order to intelligently and consciously decide what to do about those exceptions. Thus, in the method signature you specify the exceptions that the method can throw.

Checked exceptions: Java has different types of exceptions, including I/O Exceptions, runtime exceptions, and exceptions of your own creation, to name a few. Of interest to us in this discussion are runtime exceptions. Runtime exceptions are those exceptions that occur within the Java runtime system. This includes arithmetic exceptions (such as when dividing by zero), pointer exceptions (such as trying to access an object through a null reference), and indexing exceptions (such as attempting to access an array element through an index that is too large or too small).

Runtime exceptions can occur anywhere in a program and in a typical program can be very numerous. The cost of checking for runtime exceptions often exceeds the benefit of catching or specifying them. Thus the compiler does not require that you catch or specify runtime exceptions, although you can. Checked exceptions are exceptions that are not runtime exceptions and are checked by the compiler; the compiler checks that these exceptions are caught or specified.

Some consider this a loophole in Java's exception handling mechanism, and programmers are tempted to make all exceptions runtime exceptions. In general, this is not recommended.

Exceptions that can be thrown within the scope of the method: this statement may seem obvious at first: just look for the throw statement. However, this statement includes more than just the exceptions that can be thrown directly by the method: the key is in the phrase within the scope of. This phrase includes any exception that can be thrown while the flow of control remains within the method. This statement includes both:

  • Exceptions that are thrown directly by the method with Java's throw statement.
  • Exceptions that are thrown indirectly by the method through calls to other methods.

The ListOfNumbers example

The following example defines and implements a class named ListOfNumbers. The ListOfNumbers class calls two methods from classes in the Java packages that can throw exceptions.

Code:



// Note: This class won't compile by design!
// See ListOfNumbersDeclared.java or ListOfNumbers.java
// for a version of this
class that will compile.
import java.io.*;
import java.util.Vector;
public class ListOfNumbers {
    private Vector victor;
    private static final int size = 10;
    public ListOfNumbers () {
        victor = new Vector(size);
        for (int i = 0; i < size; i++)
        victor.addElement(new Integer(i));
    }
    public void writeList() {

    PrintWriter out=
                  new PrintWriter(new FileWriter("OutFile.txt"));
    for (int i = 0; i < size; i++)
        out.println("Value at: " + i + " = " + victor.elementAt(i));
        out.close();
    }
}

Upon construction, ListOfNumbers creates a Vector that contains ten Integer elements with sequential values 0 through 9. The ListOfNumbers class also defines a method named writeList that writes the list of numbers into a text file called OutFile.txt.

The writeList method calls two methods that can throw exceptions. First, the following line invokes the constructor for FileWriter, which throws an IOException if the file cannot be opened for any reason:

out = new PrintWriter(new FileWriter("OutFile.txt"));

Second, the Vector class's elementAt method throws an ArrayIndexOutOfBoundsException if you pass in an index whose value is too small (a negative number) or too large (larger than the number of elements currently contained by the Vector). Here's how ListOfNumbers invokes elementAt:

out.println("Value at: " + i + " = " +
victor.elementAt(i));

If you try to compile the ListOfNumbers class, the compiler prints an error message about the exception thrown by the FileWriter constructor, but does not display an error message about the exception thrown by elementAt. This is because the exception thrown by the FileWriter constructor, IOException, is a checked exception and the exception thrown by the elementAt method, ArrayIndexOutOfBoundsException, is a runtime exception. Java requires that you catch or specify only checked exceptions.


5168 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Thursday, February 28, 2008 (21:16:41) (17813 reads)

Exceptions -II: What's an exception and why do I care?

Go to all tips in Java Lectures by Anatoliy Malyarenko

Advantage 3: grouping error types and error differentiation

Part I was published here.

Often exceptions fall into categories or groups. For example, you could imagine a group of exceptions, each of which represents a specific type of error that can occur when manipulating an array: the index is out of range for the size of the array, the element being inserted into the array is of the wrong type, or the element being searched for is not in the array. Furthermore, you can imagine that some methods would like to handle all exceptions that fall within a category (all array exceptions), and other methods would like to handle specific exceptions (just the invalid index exceptions, please).


Because all exceptions that are thrown within a Java program are first-class objects, grouping or categorisation of exceptions is a natural outcome of the class hierarchy. Java exceptions must be instances of Throwable or any Throwable descendant. As for other Java classes, you can create subclasses of the Throwable class and subclasses of your subclasses. Each "leaf" class (a class with no subclasses) represents a specific type of exception and each "node" class (a class with one or more subclasses) represents a group of related exceptions.

For example, in the following diagram, ArrayException is a subclass of Exception (a subclass of Throwable) and has three subclasses.

InvalidIndexException, ElementTypeException, and NoSuchElementException are all leaf classes. Each one represents a specific type of error that can occur when manipulating an array. One way a method can catch exceptions is to catch only those that are instances of a leaf class. For example, an exception handler that handles only invalid index exceptions has a catch statement like this:

Code:

catch (InvalidIndexException e) {
  . . .
}

ArrayException is a node class and represents any error that can occur when manipulating an array object, including those errors specifically represented by one of its subclasses. A method can catch an exception based on its group or general type by specifying any of the exception's superclasses in the catch statement.

For example, to catch all array exceptions regardless of their specific type, an exception handler would specify an ArrayException argument:

Code:

catch (ArrayException e) {
  . . .
}

This handler would catch all array exceptions including InvalidIndexException, ElementTypeException, and NoSuchElementException. You can find out precisely which type of exception occurred by querying the exception handler parameter e. You could even set up an exception handler that handles any Exception with this handler:

Code:

catch (Exception e) {
  . . .
}

Exception handlers that are too general, such as the one shown here, can make your code more error prone by catching and handling exceptions that you didn't anticipate and therefore are not correctly handled within the handler. We don't recommend writing general exception handlers as a rule.

As you've seen, you can create groups of exceptions and handle exceptions in a general fashion, or you can use the specific exception type to differentiate exceptions and handle exceptions in an exact fashion.

Your first encounter with Java exceptions

The following error message is one of two similar error messages you will see if you try to compile the class InputFile, because the InputFile class contains calls to methods that throw exceptions when an error occurs:

InputFile.java:8: Warning: Exception java.io.FileNotFoundException must be caught, or it must be declared in throws clause of this method.

in = new FileReader(filename);

The Java language requires that methods either catch or specify all checked exceptions that can be thrown within the scope of that method. If the compiler detects a method, such as those in InputFile, that doesn't meet this requirement, it issues an error message like the one shown above and refuses to compile the program.

Let's look at InputFile in more detail and see what's going on.

The InputFile class wraps a FileReader and provides a method, getWord, for reading a word from the current position in the reader.

Code:

// Note: This class won't compile by design!
import java.io.*;
public class InputFile {
    private FileReader in;
    public InputFile(String filename) {
        in = new FileReader(filename);

    }
    public String getWord() {
        int c;
        StringBuffer buf = new StringBuffer();
        do {
        c = in.read();
        if (Character.isWhitespace((char)c))
            return buf.toString();
        else
            buf.append((char)c);
        } while (c != -1);
        return buf.toString();
    }
}

The compiler prints the first error message because of the bold line in the above code listing. The bold line creates a new FileReader object and uses it to open a file whose name is passed into the FileReader constructor.

So what should the FileReader do if the named file does not exist on the file system? Well, that depends on what the program using the FileReader wants to do. The implementers of FileReader have no idea what the InputFile class wants to do if the file does not exist. Should the FileReader kill the program? Should it try an alternate filename? Should it just create a file of the indicated name?

There's no possible way the FileReader implementers could choose a solution that would suit every user of FileReader. So, they punted, or rather, threw, an exception. If the file named in the argument to the FileReader constructor does not exist on the file system, the constructor throws a java.io.FileNotFoundException. By throwing an exception, FileReader allows the calling method to handle the error in whatever way is most appropriate for it.

As you can see from the code, the InputFile class completely ignores the fact that the FileReader constructor can throw an exception. However, as stated previously, the Java language requires that a method either catch or specify all checked exceptions that can be thrown within the scope of that method. Because the InputFile class does neither, the compiler refuses to compile the program and prints an error message.

In addition to the first error message shown above, you also see the following similar error message when you compile the InputFile class:

InputFile.java:15: Warning: Exception java.io.IOException must be caught, or it must be declared in throws clause of this method.

while ((c = in.read()) != -1) {

The InputFile class's getWord method reads from the FileReader that was opened in InputFile's constructor. The FileReader read method throws a java.io.IOException if for some reason it can't read from the file. Again, the InputFile class makes no attempt to catch or specify this exception. Thus you see the second error message.

At this point, you have two options. You can either arrange to catch the exceptions within the appropriate methods in the InputFile class, or the InputFile methods can "duck" and allow other methods further up the call stack to catch them. Either way, the InputFile methods must do something, either catch or specify the exceptions, before the InputFile class can be compiled. For the diligent, there's a class, InputFileDeclared, that fixes the bugs in InputFile by specifying the exceptions.


7326 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Thursday, February 28, 2008 (20:57:24) (5774 reads)

Previous 1060 Stories (530 Pages, 2 Per Page) Next

530|
529
| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489| 488| 487| 486| 485| 484| 483| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469| 468| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420| 419| 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363| 362| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy