Is IllegalStateException appropriate for an immutable object?
No, because immutable objects have only one state and cannot be transferred from one legal state to another.
So you create an immutable object, and your object should have a max method
class YourObject { public BigInteger max(){ ... } }
I this case of IllegalAgumentException should be correct, but only until this method is executed, but when the object is created!
So, in this case, if you have an immutable bigintegers collection and you create it with null elements, you get an “invalid argument” when creating the collection when you need to throw an exception.
I agree with John, if in your use case or in your analysis you are ready to support the rest of the operations, you can throw a NoSuchElementException , but I think that would postpone the problem. It would be better to avoid creating the object in the first place.
So, throwing an IllegalArgumentException will look like this:
// this is my immutable object class final class YourObject { private final Collection<BigInteger> c; public YourObject( BigInteger ... values ) { if( values.length == 0 ) { throw new IllegalAgumentException("Must specify at least one value"); } ... initialize the rest... } public BigInteger max() { // find and return the max will always work } }
Client:
YourObject o = new YourObject(); // throws IllegalArgumentException // the rest is not executed.... doSomething( o ) ; ... doSomething( YourObject o ) { BigInteger maximum = o.max(); }
In this case, you do not need to check anything in doSomething , because the program will fail when creating an instance, which, in turn, will be fixed during development.
Throwing NoSuchElementException will look as follows:
final class YourObject { private final Collection<BigInteger> c; public YourObject( BigInteger ... values ) {
Client:
YourObject o = new YourObject(); // it says nothing doSomething( o ) ; ... doSomething( YourObject o ) { BigInteger maximum = o.max();// ooops!, why? what?... // your object client will start questioning what did I do wrong // and chais of if( o != null && o.isEmpty() || moonPhaseIs... ) }
Keep in mind that if a program fails, the best thing you can do is for it to fail quickly .
Collections.max has a different purpose, because, being a utility method (not an immutable object), it cannot be held responsible for the empty (it was not present when it happened), the only thing it can do is say: "In this collection there is no such thing as max ", therefore, NoSuchElementException.
One final note, RuntimeExceptions, should only be used to program errors (those that can be fixed by testing the application before release)