Please support my sponors and make this site possible!!!
Please support our sponsors!

 

Home > Core Java FAQ > Exception Handling FAQ
Exception Handling
 
Q .  What is an exception?

Ans : 

An exception is a condition (typically an error condition) that transfers program execution from a thrower (at the source of the condition) to a catcher (handler for the condition); information about the condition is passed as an Exception or Error object.

     An exception provides a communication channel between one portion of code that detects and signals an (error) condition, and another portion of code that responds to the condition. Exceptions in some ways resemble method invocations, as highlighted in Table 2.8. In both cases, information and control of execution pass from one portion of code to another. And in both cases, the initiator of the exchange typically doesn't know, and doesn't need to know, precisely what code will respond.

Table 2.8: Throwing an Exception versus Invoking a Method
Instigator/Requester Communication mechanism Responder/Performer
throw statement Exception object executes catch clause
method invocation expression dynamic method lookup; arguments and return value executes method body

     It is important to remember, however, that exceptions should be used only for exceptional control flow needs. Exceptions typically signal unexpected error conditions, such as:

  • IllegalArgumentException: a method argument violates some requirement
  • NullPointerException: a method is invoked on a null reference
  • ArrayIndexOutOfBoundsException: an array index is too small or too large

     The Java language represents exceptions as objects, all of which belong to the Throwable class or one of its subclasses. Because exceptions belong to classes, you can readily define your own exception types by subclassing an existing exception class.
     There are four main ways to interact with Java's exception system, listed below in a common order that programmers learning Java encounter them:

  • catching exceptions thrown by other people's code
  • writing your own code to throw exceptions
  • declaring exceptions that a method can throw
  • defining your own Exception classes

What follows is a bare-bones how-to introduction for each of these facets.
     To catch an exception, you specify a body of code to watch, a type of exception to watch for, and a body of code to execute if an appropriate exception type is thrown within the watched body of code. For example:

     int anIntValue;
     String str = solicitStringFromUser();
    try {
         anIntValue = Integer.parseInt(str);
     } catch (NumberFormatException e) {
         reportError("string could not be parsed as an Integer.")
     }

     To throw an exception, use the throw statement and provide a newly created Exception instance, which can include a message providing information about this particular exception:

     int speed;  // an instance variable
     public void setSpeed(int value) throws IllegalSpeedException {
         if (value < 0) {
             throw new IllegalSpeedException(
                       "speed cannot be negative");
         }
         speed = value;  // executed only for valid speed values.
     }

The above code also illustrates how to declare an exception: you provide a throws declaration following the method's parameter list. Note that both methods and constructors can throw and declare exceptions.
     Finally, to define a new Exception class, subclass Exception or one of its subclasses, and provide appropriate constructors. The IllegalSpeedException used in the previous example is not a predefined Java class; you could define it yourself:

     class IllegalSpeedException extends Exception {
         public IllegalSpeedException() { super(); }
         public IllegalSpeedException(String s) { super(s); }
     }
Q . Why does the compiler complain about InterruptedException when I try to use Thread's sleep method?

Ans : 

The compiler is complaining, as it is required to do, that your code invokes a method that might throw a checked exception, but your code is not prepared to handle that exception; to stop the compiler from complaining, your method must either declare or catch the InterruptedException that Thread's sleep method can throw.

     InterruptedException belongs to the set of checked exceptions— a subset of exceptions that a Java compiler is required to track through any source code it handles. One of the compiler's restrictions is that a method declare all the checked exceptions that it might throw. A method can throw an exception either by an explicit throw statement or by invoking another method that throws the exception.
     Thread's sleep method declares that it can throw an InterruptedException; therefore, the compiler will examine any method that invokes sleep to check whether the exception is being dealt with. You have two options when writing a method that invokes sleep:

  • declare that your method can throw InterruptedException
  • catch the exception inside your run code

     To declare the exception, add a throws clause to your method definition:

     public void myMethod() throws InterruptedException { /* ... */ }

This is a simple fix, but it also means that you are leaving it up to some other method to catch and deal with the exception.
     It is often better to catch an exception right at the point it is generated, where you usually have more information about what triggered the exception. To catch the exception, surround your call to sleep in a try-catch block:

     try {
             Thread.sleep(sleepTime);
         } catch (InterruptedException e) {
             // ... handle the exception here (good)
             // or leave this blank to ignore the exception (risky)
             // but still satisfy the compiler
      }
Q . Why do methods have to declare the exceptions they can throw?

Ans :  

The simple answer is that the Java language requires it; the more meaningful answer is that the language requires exception declarations because they enhance the usability and robustness of code as part of an API.

     The Java language requires that a method declare any checked exceptions that the method might throw. Whether an exception is checked or not depends on the exception's class. As shown in Table 2.9, the base Throwable class splits into two main subclass branches, Error and Exception. All Exception subclasses are checked exceptions except for RuntimeException and its subclasses. 

 

Table 2.9: Checked Expections versus Unchecked Exceptions
Class hierarchy under Throwable Checked?
Throwable Error and its subclasses no
Exception RuntimeException and its subclasses no
all other Exception subclasses yes

     The intent of checked exceptions is that you declare exceptions as a meaningful part of your class's programming interface. Together with a method's return value, exceptions define the output behavior of the method. Any code that invokes a method must be prepared to handle either of these:

  • the method's return value, if the method completes normally
  • any of the method's checked exceptions, if the method terminates abnormally

Checked exceptions thus complement the return value as indicators of a method's exit status.
     For example, the InputStream class in the java.io package includes a read method that is declared as follows:

     public byte read() throws IOException;

This means that any method invoking this read method must be prepared to handle two kinds of outcome from the method: a byte return value if the read succeeds, or an IOException if the read fails. The invoking method itself must therefore either catch the exception or declare that it, too, throws IOException.
     The requirement that checked exceptions be declared or caught is not just good programming practice—it is a rule enforced by the Java compiler. More specifically, the compiler enforces the following condition:

If method X invokes method Y, and method Y can throw a checked exception, then either method X must catch the exception, or method X must declare the exception (or a superclass of the exception).

     The real power of this check is that the compiler performs it transitively, following the often-complex chain of possible method invocations (method X invokes method Y, which in turn might invoke method Z, and so on).
     This moderate degree of automated error checking provides surprisingly strong help in writing robust, error-tolerant code. One example comes from the development of Java and HotJava themselves. When exception declarations and exception checking were added to the language, this immediately turned up a number of cases in which the HotJava developers hadn't noticed they needed to catch certain important types of exceptions. Instead of being caught further down the road as tricky run-time bugs, these mistakes were now being flagged as compile-time errors. The developers thus were able to find and fix the problems much more efficiently. The extra effort of declaring checked exceptions was repaid many times. Such experiences advise against circumventing these built-in checks without strong reason (and even then, think twice).
Q . What's the difference between a runtime exception and a plain exception-why don't runtime exceptions have to be declared?

Ans :  

The Java language specifies that all runtime exceptions are exempted from the standard method declarations and compiler checks; such exceptions belong more to the system as a whole than to the method that happens to be executing when the exception is thrown.

     The Java language lets you signal conditions (usually error conditions) by throwing an object at one point in your code, such that an enclosing block can catch the object and infer from it the trigger condition. The object you throw must belong to the Throwable class or one of its subclasses. The class hierarchy under Throwable further classifies the nature of the unusual condition. Throwable subdivides into two subclasses, which The Java Application Programming Interface (Vol. 1) demarcates nicely:

  • Error: "indicates serious problems that a reasonable application should not try to catch." (p. 175)
  • Exception: "indicates conditions that a reasonable application might want to catch." (p. 162)

     Errors are never declared—they are entirely unexpected and practically always fatal. When an Error instance is thrown and not caught, it works its way up the method invocation stack until the Java Virtual Machine detects it, prints out a diagnostic error message (usually including a useful stack trace), and then kills that thread. (Uncaught Exception instances have this same behavior.)
     Exceptions come in two basic varieties-those that can be ascribed to the execution of a single method and those that belong more to the system as a whole:

  • Exception (in general): meaningful, specific, recoverable condition that can be expected to arise occasionally in the execution of this method (for instance, a NumberFormatException thrown when trying to parse a String instance as an Integer value).
  • RuntimeException: a condition that can arise in principle anytime, largely independent of which particular method happens to be executing (for instance, an ArrayIndexOutOfBoundsException).

     Exceptions in general must be declared by methods (and by constructors) and are checked by the compiler. Runtime exceptions are exempted from this because the Java designers judged that having to declare them would be too much work, would involve too many methods, and would not pay back the extra effort sufficiently in terms of increased program robustness.
     The difference between runtime exceptions and other exceptions is not always clear-cut— it requires human judgment as to the relative merits of including the exception as a method-specific condition versus a can happen-anytime general condition. Nevertheless, making the distinction reflects Java's pragmatic streak:

  • It presents a balance between theoretical purity and practical needs.
  • It helps developers write convenient yet robust code.

     Recommendation: Use general (declared) exceptions wherever possible. In the experience of many Java developers, the benefits of automatic compile-time checking more than offset the extra effort of declaring or catching exceptions.

Q . Given a method that doesn't declare any exceptions, can I override that method in a subclass to throw an exception?

Ans :  

No; subclasses must honor the API contract established by their superclasses, and this includes the types of checked exceptions that a method can throw.

     An API (application programming interface) establishes a contract of intent, not just of form or interpretation. To borrow terminology from linguistics and philosophy, an API contract involves both extension and intension: the boundaries of the current state of the world (extension) as well as the intended boundaries for other possible states of the world (intension: possible future implementations). In object-oriented programming, a common source of "possible future implementations" is subclassing from an existing class in an API.
     A method defines a contract for any subclass method that would override it; it constrains possible implementations that a subclass could provide. In Java, the bare minimum contract for a method's inputs and outputs is the following:

  • A method's parameter list is fixed; an overriding method in a subclass must declare precisely the same number and types of arguments.
  • A method's return type is fixed; an overriding method in a subclass must declare precisely the same return type.
  • The set of checked exceptions a method can throw (the method's declared exception classes and all their subclasses) establishes an upper bound. An overriding method in a subclass cannot throw any checked exceptions outside of that; it can, however, throw fewer exception types, or even none at all.

Note that the contract on exceptions concerns only checked exceptions; errors and runtime exceptions (that is, Error, RuntimeException, and their subclasses) are always permitted.
     If a method, such as Object's toString method, is declared as throwing no checked exceptions, any overriding method you define must live within those bounds. You cannot define your own subclass of Exception and have your toString method throw that. In such a case, if you really need some exception to be thrown, you can resort to a subclass of RuntimeException, which is not checked or constrained by the compiler.

Q . Why do I get the java.lang.UnsatisfiedLinkError when I run my Java program containing Native Method invocations?

Ans : Your program is not able to find your shared library or DLL.

On Windows 95/NT, make sure that the DLL exists in a path that is included within the PATH environment variable. (This need is true for both standard (untrusted) applications and trusted applets. At least, if you use the Java Plug-in to give yourself standard Java inside a browser).

On Solaris, make sure that the environment variable LD_LIBRARY_PATH includes the path of your shared library.

Note that jdb looks for libraries with "_g" appended to their names. Thus, if you intend to use jdb on a Java application that invokes native methods, you must ensure that the appropriately named libraries
are in jdb's path. The "debug" nm libraries can simply be renamed copies of the nondebug libraries.

For example, if your app invokes native methods in a library named mynm.dll (on Windows) or mynm.so (on Solaris), make a copy in the same directory and name it mynm_g.dll or mynm_g.so.

Q . Variable may not have been initialized.

Ans : URL test;
try {
test = new URL("http://osprey.avs.dec.com");
} catch (MalformedURLException e) {
System.out.println("bad URL:" + e.getMessage());
}
System.out.println("this is url " + test);


The compiler will warn you if you use a variable before it is certain to have been initialized (not just with the default value) since this means you probably forgot to set it.

In the case of exceptions, you have to consider that the flow of control may terminate abruptly, with no operations completed. In the example above, if an exception is raised in the try clause, variable test will not be assigned a value, yet you are using it after the catch clause. One solution would be to declare test with an explicit initial value of null, but this works only because toString() works on a null reference. (toString() is invoked implicitly by operator + with String operand.)

Always initialize to a value that will work notwithstanding exceptions being thrown.

Q . No constructor {superclass}()...?

Ans : I extended the class called Frotz, and the compiler is giving me an error message "No constructor Frotz()" in the child class. Why?

When you define a constructor for a class, the compiler inserts a call to the superclass' parameterless constructor unless you explicitly call the superclass' constructor at the start of your constructor. If
the superclass doesn't *have* a parameterless constructor, the compiler emits a message to that effect. The solution is usually to call the superclass' constructor at the start of your constructor.

Q . No constructor matching MyCheckbox(myApplet)

Ans : MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
found in class MyCheckbox.

bp1 = new MyCheckbox(this);
^

If a compiler isn't finding a constructor you thought you created, check whether you gave a return value to the method (remember, constructors have no return value). E.g.,

public void MyCheckbox( Container parent )

If you did, the compiler will think it is an ordinary method, not a constructor. This is a common mistake and hard to spot.

 

Copyright © 2000 javafaq.com. All rights reserved