What is the intentional use of IllegalStateException?

This appeared in a discussion with a colleague today.

Javadocs for Java IllegalStateException state that it:

Signals that the method was called at an illegal or inappropriate time. In other words, the Java environment or Java application is not in the appropriate state for the requested operation.

And effective Java says (Paragraph 60, page 248):

Another commonly used exception is IllegalStateException. This is usually an exception for a throw if the call is illegal due to the state of the receiving entity. For example, this would be a throw exception if the caller tried to use an object before it was correctly initialized.

There seems to be a bit of a discrepancy. In the second sentence, javadocs sounds like an exception can describe a very broad condition for the state of execution of Java, but the description in Effective Java makes it look like conditions related specifically to the state of the state of the object, the method was called.

Devices that I saw in the JDK (like collections, Matcher ) and in Guava definitely seem to fall into the category Effective Java talks about ("This object is in a state where this method cannot be called"). It is also similar to IllegalStateException sibling IllegalArgumentException .

Are there legal IllegalStateException services in the JDK that refer to the "Java environment" or the "Java application"? Or do any best practice recommendations promote its use for a wider state of execution? If not, then why are these the so-called javadocs ?;)

+62
java exception illegalstateexception
Oct 02
source share
6 answers

Here is one particularly legitimate use of this exception in the JDK (see URLConnection.setIfModifiedSince(long) among more than 300 of its other uses:

 public void setIfModifiedSince(long ifmodifiedsince) { if (connected) throw new IllegalStateException("Already connected"); ifModifiedSince = ifmodifiedsince; } 

I think the example is pretty clear. If the object is in a certain state ("Already connected"), some operations should not be called. In this case, when the connection is established, some properties cannot be set.

This exception is especially useful when your class has some state (finite state machine?) That changes over time, making some methods irrelevant or impossible. Think of the Car class, which has the start() , stop() and fuel() methods. Calling start() twice, one after the other, is probably nothing bad, but refueling a running car is definitely a bad idea. Namely - the car is in an improper condition.

Perhaps a good API should not allow us to call methods in the wrong state so that such problems are detected at compile time rather than at run time. In this particular example, connecting to the URL should return another object with a subset of methods, all of which are valid after the connection.

+32
Oct 02
source share

Here is an example in the JDK. There is a private class package called java.lang.Shutdown. If the system closes and you try to add a new hook, it throws an IllegalStateException. It can be argued that this meets the criteria of the javadoc manual because the Java environment is in an incorrect state.

 class Shutdown { ... /* Add a new shutdown hook. Checks the shutdown state and the hook itself, * but does not do any security checks. */ static void add(int slot, Runnable hook) { synchronized (lock) { if (state > RUNNING) throw new IllegalStateException("Shutdown in progress"); if (hooks[slot] != null) throw new InternalError("Shutdown hook at slot " + slot + " already registered"); hooks[slot] = hook; } } 

However, it also illustrates that there really is no difference between the javadoc manual and the Effective Java manual. Due to how Shutdown is executed, the shutdown-ness JVM is stored in a field called state. Therefore, it also complies with the "Effective Java" guidelines when to use IllegalStateException, since the "state" field is part of the state of the receiving object. Since the receiving object (Shutdown) is in the wrong state, it throws an IllegalStateException.

In my opinion, two descriptions of when to use IllegalStateException are sequential. An effective Java description is a little more practical, all. For most of us, the most important part of the entire Java environment is the class that we are writing now, so the author focuses on this.

+3
02 Oct
source share

I assume that if you see the use of IllegalStateException , I would say the second, if that is more appropriate. This exception is used in many packages.

  • java.net
  • java.nio
  • java.util
  • java.util.concurrrent etc.

To indicate one example, ArrayBlockingQueue.add throws this exception if the queue is already full. Now the complete state of the object and it is called at the wrong or illegal time

I think both options mean the same thing, but the difference in wording.

0
Oct 02
source share

There is no "inconsistency." There is nothing in the Bloch wording that excludes what she says in JLS. Bloch simply says that if you have circumstance A, throw this exception. He does not say that this exception / should be thrown only in this state. JLS says this exception is thrown if A, B or C.

0
03 Oct '12 at 0:00
source share

I came across this:

 try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); ... } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } 

I think it would be inappropriate for me to throw an IllegalStateException instead of an AssertionException , although this falls into the Java environment category.

0
May 01 '14 at 2:02
source share

Given the library, it should throw an IllegalStateException or IllegalArgumentException whenever it detects an error due to user code, while the library should throw an AssertionError whenever it encounters an error due to its own library implementation.

For example, in library tests, you can expect the library to throw an IllegalStateException when the order of method calls is incorrect. But you never expect the library to throw an AssertionError .

0
Apr 02 '16 at 7:54 on
source share



All Articles