Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2007

Tip: Looking for answers? Try searching our database.

Use of AssertionError

Thread view: 
Joshua Cranmer - 30 Dec 2007 20:50 GMT
Having just read the
NullPointerException-IllegalArgumentException-AssertionError thread, I
was just wondering if my use of AssertionError in one case was valid.
This is a very pared-down interface of the code:

import java.util.*;

public final class ClassPool {
    public interface SourceHandler {
        public boolean hasClass(String name);
    }

    private static List<SourceHandler> handlers =
        new LinkedList<SourceHandler>();

    static {
        // add a few handlers to the list...
        handlers.add(new SourceHandler() {
            public boolean hasClass(String name) {
                return true;
            }});
        // This is not really an anonymous inner class, but it is the
        // best way for me to make it compilable
    }

    // The user can add handlers but can never remove them.
    public static void addHandler(SourceHandler handler) {
        handlers.add(0, handler);
    }

    // Edited for simplicity
    public static void getClass(String name) {
        for (SourceHandler handler : handlers) {
             if (handler.hasClass(name))
                 return; // Use this handler as the class
        }
        // Since our last handler claims to handle everything, we should
        // never get here.
        throw new AssertionError();
    }
}

Where I throw the assertion error explicitly, I want to put an `assert
false;' statement in (with a comment, of course), but then I would need
to insert a `return null;' at the end of the method, which would
invalidate the method contract which forbids null as a result but
assertions may not be on.

Is it more appropriate to put a RuntimeException or other type of error
instead of using an AssertionError here?
Signature

Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Mark Thornton - 30 Dec 2007 21:44 GMT
> Having just read the
> NullPointerException-IllegalArgumentException-AssertionError thread, I
[quoted text clipped - 21 lines]
> Is it more appropriate to put a RuntimeException or other type of error
> instead of using an AssertionError here?

If it ever did happen you would be annoyed that the error message didn't
include the name for which no handler was found. So at least pass 'name'
to the constructor.

Mark Thornton
Lew - 30 Dec 2007 21:49 GMT
>     public static void getClass(String name) {
>         for (SourceHandler handler : handlers) {
[quoted text clipped - 15 lines]
> Is it more appropriate to put a RuntimeException or other type of error
> instead of using an AssertionError here?

I would use IllegalStateException.  The problem is that this depends on data
being wrong, i.e., a run-time condition that caused 'handlers' not to be
initialized correctly.  This is not an algorithmic failure but a state
failure.  The program is in an illegal state, therefore IllegalStateException.

Client code will not be able to recover from an AssertionError.  Is that what
you want, or would you prefer that the client can detect and log the
exception, perhaps by plugging in its own default handler when it hits this?

Don't you think it might surprise a sysadmin to see an AssertionError if
they've turned off asserts?

Signature

Lew

Daniel Pitts - 30 Dec 2007 22:34 GMT
>>     public static void getClass(String name) {
>>         for (SourceHandler handler : handlers) {
[quoted text clipped - 29 lines]
> Don't you think it might surprise a sysadmin to see an AssertionError if
> they've turned off asserts?

How about this case:

public String getSomethingRandom() {
  final int value = random.nextInt(3);
  switch (value) {
    case 0:
      return "Nothing here.";
    case 1:
      return "Got something!";
    case 2:
      return "Twice the fun?";
    default:
      throw new AssertionError("Something wrong!");
  }
}

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Patricia Shanahan - 30 Dec 2007 23:09 GMT
>>>     public static void getClass(String name) {
>>>         for (SourceHandler handler : handlers) {
[quoted text clipped - 45 lines]
>   }
> }

How about:

assert false : "Something wrong!";

in code that should never be reached. That way, disabling assertions
does prevent throws of AssertionError, and AssertionError does indicate
an assertion has failed.

Patricia
Daniel Pitts - 30 Dec 2007 23:29 GMT
>>>>     public static void getClass(String name) {
>>>>         for (SourceHandler handler : handlers) {
[quoted text clipped - 56 lines]
>
> Patricia
You'll get a compiler error if you use assert false;  Left up as an
exercise for the reader.

Signature

Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>

Eric Sosman - 31 Dec 2007 14:39 GMT
> [...]
> You'll get a compiler error if you use assert false;  Left up as an
> exercise for the reader.

    Okay, I've exercised until I got cramps in my thinking
muscle, but I got no compiler errors.  Could you elucidate?

Signature

Eric Sosman
esosman@ieee-dot-org.invalid

Patricia Shanahan - 31 Dec 2007 14:54 GMT
>> [...]
>> You'll get a compiler error if you use assert false;  Left up as an
>> exercise for the reader.
>
>     Okay, I've exercised until I got cramps in my thinking
> muscle, but I got no compiler errors.  Could you elucidate?

If you simply replaced the throw with an assertion, with no other
changes, there would be a fall-through path to the end of the method,
not permitted in a method that returns a result.

Patricia
Lew - 31 Dec 2007 15:37 GMT
>>> [...]
>>> You'll get a compiler error if you use assert false;  Left up as an
[quoted text clipped - 6 lines]
> changes, there would be a fall-through path to the end of the method,
> not permitted in a method that returns a result.

That's why there's an exception toss after the 'assert' in the example I provided.

Signature

Lew

Lew - 31 Dec 2007 02:49 GMT
> How about this case:
>
[quoted text clipped - 11 lines]
>   }
> }

This seems like a good case for assertions, except for that disabling asserts
doesn't disable explicit throws like this one.  It's a little simplistic, but
it does illustrate an invariant.

Here's more of a realistic use case for assert:  replace the literal '3' with
a variable coming from a private source, that should have been constrained to
less than APP_MAXRAND.  Put the whole violated condition in the assert:

 public String getSomethingRandom()
 {
   final int value = random.nextInt( somePrivateMethod() );

   // The assert really belongs here, but it's more fun below.
   // It belongs here because here is where the invariant should hold.

   switch ( value )
   {
     case 0:
       return "Nothing here.";
     case 1:
       return "Got something!";
     case 2:
       return "Twice the fun?";
     default:
       assert value >= 0 && value < APP_MAXRAND;
       throw new IllegalStateException( "Invalid random value "+ value );
   }
 }

Signature

Lew



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.