3

I have read a few asserts vs exception questions already; I ask specifically about package visible classes though.

When you write a package, the classes marked with "public" are exposed to the outside world, thus exceptions are used to let users of the package's interface know they're using the package wrong.

The classes that are left unmarked are only exposed to the internals of the package, no? So I'm inclined to say that when something goes awry in a package visible class, assertions would be used stop the classes I have built from sending one another bad data.

Is this a fine thing to do?

I have adopted the idea that objects hold their own data as private to them and methods are public/private as needed to work internally or with other classes. Once the class is identified as doing too much, the class is split into simpler objects meant to work together.

At this point, many classes exist, but only some should be exposed to the outside world. So I have reached the conclusion that packages are like super objects, exposing just enough so that the entire "community" of classes can work together to solve the problem. This way implementation is hidden but a service is still provided.

Is that understanding correct? That is what the question is based on, since the community of classes is created in a "private to the package" manner, it is not exposed to the outside, and so, should assertions be used instead?

marked as duplicate by gnat, user40980, Bart van Ingen Schenau, jwenting, GlenH7 May 20 '14 at 13:34

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2

That is what the question is based on, since the community of classes is created in a "private to the package" manner, it is not exposed to the outside, and so, should assertions be used instead?

No. While it's true that assertions should not be part of your public contract, that doesn't mean that all non-public contracts should be enforced through assertions!

Assertions are not (solely) a matter of visibility. They are a different type of mechanism, used to signal a different type of problem.

Assertions signal logic errors inherent to the code. They are checkpoints that a programmer introduces to catch bugs early, and triggering them means that a program is no longer operating normally or predictably. Exceptions cover usage errors and unforeseen circumstances that may arise during otherwise normal execution of a program.

Here is an example that clarifies this. It's part of an implementation of java.util.Iterator:

public Object next() {
    if ( !hasNext() ) {
        // usage error: there is no next object
        throw new NoSuchElementException();
    }

    // logic error: hasNext() says okay, but there is no next element!
    assert next != null : "hasNext() but not found!";
    Object retval = next;
    next = null;
    return retval;
}

Another example that could be in a public implementation of java.util.Set:

public boolean add(Object o) {
    if ( o == null ) throw new IllegalArgumentException("does not accept null");

    added = // adding magic here

    // either it was added, or it was already in: either way, must contain now
    assert contains(o) : "added but does not contain?";
    return added;
}

Both asserts are in public methods of classes that could likewise be public. But their presence is basically there to assure me, the programmer, that my assumptions/assertions about the code that I wrote are valid. If users of my code see AssertionErrors, that means my code has a problem.


The following are bad examples of assertions:

public boolean add(Object o) {
    // disabling asserts makes the code below possibly take nulls
    assert o != null : "does not accept null";
}

public Object next() {
    // this is a usage error
    assert hasNext();
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.