The Artima Developer Community
Sponsored Link

Java Buzz Forum
Internal and External Exceptions

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Elliotte Rusty Harold

Posts: 1573
Nickname: elharo
Registered: Apr, 2003

Elliotte Rusty Harold is an author, developer, and general kibitzer.
Internal and External Exceptions Posted: Jul 21, 2007 6:44 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Elliotte Rusty Harold.
Original Post: Internal and External Exceptions
Feed Title: The Cafes
Feed URL: http://cafe.elharo.com/feed/atom/?
Feed Description: Longer than a blog; shorter than a book
Latest Java Buzz Posts
Latest Java Buzz Posts by Elliotte Rusty Harold
Latest Posts From The Cafes

Advertisement

Perhaps the continuing confusion over the difference between checked and runtime exceptions in Java is because we haven’t named them properly. Mosts texts and teachers, including myself, have traditionally focused on how and when you handle the exceptions (compile time or runtime) rather than on what causes each. I propose a modification, not in code, but in terminology and teaching. Specifically I think we should should start calling checked exceptions “external exceptions” and runtime exceptions “internal exceptions”.

The idea is this: a checked exception is a response to some external event the program does not have control over. Examples include:

  • File not found (FileNotFoundException)
  • Network socket closed midstream (SocketException)
  • Port already in use (BindException)
  • Malformed XML document (SAXParseException)
  • Database refuses request (SQLException)

Any exception caused by occurrences outside the program itself should be a checked exception.

By contrast, a runtime exception is caused by a mistake inside the program. Examples include:

  • Precondition violations (IllegalArgumentException)
  • Dereferencing null (NullPointerException)
  • Objects of the wrong type (ClassCastException)
  • Accessing outside an array (IndexOutOfBoundsException)
  • Inserting an object in a read-only collection (UnsupportedOperationException)

These should all be runtime exceptions.

When choosing between checked and runtime exceptions, simply ask yourself where the bug lies. Is the problem that causes the exception inside the program or outside it? If it’s inside, use a runtime exception. If it’s outside, use a checked exception. Simple, easy to understand, and easy to teach. And a lot clearer than complicated verbiage like

checked exceptions are for unpredictable environmental conditions such as I/O errors and XML well-formedness violations while unchecked exceptions are for program failures that should be caught during testing, such as array index out of bounds or null pointers. A checked exception usually cannot be avoided by changing your code while an unchecked exception usually can be. That is, an unchecked exception normally indicates a bug in your program, and a checked exception doesn’t.

This is especially true when you’re teaching undergrads who don’t do any testing at all, and thus for whom the distinction between bugs caught in testing and bugs caught at compile time is non-existent. I’m hopeful that it will be easier to teach them the difference between internal and external causes than the difference between bugs caught at compile time and bugs caught at runtime.

There are some borderline cases. The classic one is a user entering a string which is then converted to an int. For example,

int getNumberFromUser(TextField tf) {
    String s = tf.getText();
    return Integer.parseInt(s);
}

If the user enters a non-numeric value, getNumberFromUser throws a NumberFormatException, a runtime exception. How do we account for this?

I think we can do that by breaking this into two parts. From the perspective of the Integer.parseInt() method, a runtime exception is appropriate. The bad string is a precondition violation. An argument was passed that is not according to spec. This argument came from another part of the same program. Integer.parseInt() does not accept input from the user. Therefore, NumberFormatException is rightly a runtime exception.

The mistake here really is in the code that invokes Integer.parseInt(). It should have checked that the value was a correct numeric string before passing it to a different method. It failed to verify the user input. This program is buggy, irrespective of user input. The uncaught runtime exception indicates that.

Now for practical purposes and convenience, we may well wish to allow Integer.parseInt() to do the necessary check anyway. There’s no need to duplicate the code. However, a non-buggy invoking method should catch the runtime exception and convert it to a checked exception. For example,

int getNumberFromUser(TextField tf) throws UserInputException {
    String s = tf.getText();
    try {
        return Integer.parseInt(s);
    }
    catch (NumberFormatException ex) {
        throw new UserInputException(s + " is not a number");
    }
}

...
public class UserInputException extends Exception {

    public UserInputException(String message) {
        super(message);
    }

}

That is, we really need two methods: one that reads a string from the user and returns an integer, and one that reads a a string from another part of the program and returns an integer. The first may call the second, but these are not the same methods, and they do not throw the same exception.

It doesn’t help that a lot of APIs, even some in the core JDK, get this wrong. For example, CloneNotSupportedException always indicates an internal program bug. It really should be a runtime exception (and if it were Cloneable would be quite a bit simpler and easier to implement). In fact, I suspect the JDK might well be improved if we went through all its exception classes and recategorized them according to this scheme. But overall I do think that exceptions are neatly sorted into those caused by internal mistakes and those caused by external data. When you find a checked exception caused by internal bugs or a runtime exception caused by external conditions, chances are very good this indicates a design flaw that should be corrected.

To sum up, here’s the rule:

If the exception is caused by problems internal to the program, it’s a runtime exception. If it’s caused by problems external to the program, it’s a checked exception.

Short, simple, to the point. Are there any exceptions to this rule? Are there any cases where an internal program bug legitimately should be signaled by a checked exception or an external input error should be signaled by a runtime exception? I can’t think of any. What do you think?

Read: Internal and External Exceptions

Topic: How To Flip English Text Using Unicode - ǝpoɔıun ƃuısn ʇxǝʇ ɥsılƃuǝ dılɟ oʇ ʍoɥ Previous Topic   Next Topic Topic: JQuery 1.1.3 is 800% Faster; 20 KB

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use