commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Juozas Baliuka" <bali...@mwm.lt>
Subject Re: Checked vs Runtime exceptions
Date Wed, 25 Jun 2003 10:23:25 GMT


 Checked exeptions look very usefull for API designers and useless for API
users, doe's not it ?


> You missed the correct solution in your logging
> example.  Obviously, various implementations will
> throw different sets of exceptions so the right way to
> handle it is to create a checked LoggingException and
> throw that from the log methods.  The implementations
> will wrap their exceptions in LoggingExceptions.  This
> keeps all of the advantages of checked exception
> handling without resorting to throwing/catching
> Exception.
>
> RuntimeExceptions indicate programmer error.  In rare
> cases they are thrown when you must bypass several
> application layers (see SecurityException for an
> example).
>
> David
>
> --- Rodney Waldhoff <rwaldhoff@apache.org> wrote:
> > I'm not sure that "ownership" necessarily enters
> > into it, but here's some
> > concrete examples:
> >
> > Consider a simple logging API:
> >
> > interface Log {
> >   void debug(String message);
> >   void info(String message);
> >   void fatal(String message);
> > }
> >
> > One implementation of that interface might write the
> > output to standard
> > out.  Since System.out (java.io.PrintStream I guess)
> > never throws a
> > checked exception, there's no need to ever throw a
> > checked exception from
> > that implementation or that interface.
> >
> > Another implementation of that interface might write
> > to some external
> > file.  Any of those write calls might throw an
> > IOException, in which case
> > I should add "throws IOException" to all of my
> > logging methods unless I'm
> > gonna swallow all of those exceptions (while
> > swallowing exceptions *might*
> > be OK in the logging case, it certainly isn't OK in
> > the general case).
> >
> > interface Log {
> >   void debug(String message) throws IOException;
> >   void info(String message) throws IOException;
> >   void fatal(String message) throws IOException;
> > }
> >
> > Now even if I'm using a System.out logger, I've got
> > to catch or throw
> > IOException, just in case.
> >
> > Yet another implementation of that interface might
> > write log messages to a
> > database.  Any of those insert statements might
> > throw a SQLException, in
> > which case I should add "throws SQLException" to all
> > my logging methods:
> >
> > interface Log {
> >   void debug(String message) throws IOException,
> > SQLException;
> >   void info(String message) throws IOException,
> > SQLException;
> >   void fatal(String message) throws IOException,
> > SQLException;
> > }
> >
> > Of course, I'll never be able to anticipate all of
> > the specific types of
> > Exception that might be thrown.  I may as well drop
> > back to the general
> > case:
> >
> > interface Log {
> >   void debug(String message) throws Exception;
> >   void info(String message) throws Exception;
> >   void fatal(String message) throws Exception;
> > }
> >
> > but now I have all of the disadvantages of checked
> > exceptions--I need to
> > explictly catch or throw Exception every time I
> > invoke one of these
> > methods--but none of the advantages of checked
> > exceptions--I don't have
> > any guarentee that the specific type of exception
> > that might be throw by
> > the implementation code is going to be specifically
> > handled by the calling
> > code.  How's this any better than RuntimeException?
> >
> > As another example, consider java.util.Iterator.  I
> > can do lots of useful
> > things with Iterators (chain them, filter them,
> > transform them, apply some
> > function to each element within the iteration,
> > etc.).  One source of
> > Iterators is the Collections API.  But it's not
> > difficult to create an
> > Iterator from other sources--say an Iterator over
> > the lines in a file:
> >
> > class LineIterator implements Iterator {
> >   LineIterator(BufferedReader reader) {
> >      this.reader = reader;
> >   }
> >
> >   Object next() {
> >     if(hasNext()) {
> >        nextSet = false;
> >        return nextLine;
> >     } else {
> >        throw new NoSuchElementException();
> >     }
> >   }
> >
> >   boolean hasNext() {
> >     if(!nextSet) {
> >       setNext();
> >     }
> >     return nextLine != null;
> >   }
> >
> >   private setNext() throws IOException {
> >      nextLine = reader.readLine();
> >      nextSet = true;
> >   }
> >
> >   private Reader reader;
> >   private String nextLine;
> >   private boolean nextSet = false;
> > }
> >
> > or the values in some column in a database table:
> >
> > class ColumnIterator implements Iterator {
> >   ColumnIterator(ResultSet rset, int column) {
> >      this.rset = rset;
> >      this.column = column;
> >   }
> >
> >   Object next() {
> >     if(hasNext()) {
> >        nextSet = false;
> >        return next;
> >     } else {
> >        throw new NoSuchElementException();
> >     }
> >   }
> >
> >   boolean hasNext() {
> >     if(!nextSet) {
> >       setNext();
> >     }
> >     return nextSet;
> >   }
> >
> >   private setNext() throws SQLException {
> >      if(rset.next()) {
> >         next = rset.getString(column);
> >         nextSet = true;
> >      } else {
> >         nextSet = false;
> >      }
> >   }
> >
> >   private ResultSet rset;
> >   private int column;
> >   private Object next;
> >   private boolean nextSet = false;
> > }
> >
> > Of course, those don't quite work because the
> > checked IOExceptions and
> > SQLExceptions aren't being handled.  In theory, one
> > could add "throws
> > Exception" to all of the Iterator methods (subject
> > to the limitations
> > above), but in practice that's not going to happen.
> >
> > Why not just throw RuntimeException in this case
> > (and ignore the tunneling
> > concept)?  Because there are times when I might be
> > able to handle or
> > announce the underlying cause:
> >
> > // process the commands in the given stream,
> > ignoring lines that start
> > with #
> > void processCommandStream(Reader in) throws
> > IOException {
> >    UnaryPredicate startsWithHash = new
> > UnaryPredicate() {
> >       public boolean evaluate(Object obj) {
> >          return ((String)obj).startsWith("#");
> >       }
> >    }
> >
> >    Iterator iterator = new FilteringIterator(
> >       new NotPredicate(startsWithHash),
> >       new LineIterator(in));
> >
> >    try {
> >      while(iterator.hasNext()) {
> >         processCommand((String)iterator.next());
> >      }
> >    } catch(TunneledException e) {
> >      if(e.getException() instanceof IOException) {
> >         throw (IOException)(e.getException());
> >      }
> >    }
> >
> === message truncated ===
>
>
> __________________________________
> Do you Yahoo!?
> SBC Yahoo! DSL - Now only $29.95 per month!
> http://sbc.yahoo.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message