In this article, we are going to look at IllegalStateException
in java, its meaning and the reason why it occurs.
IllegalStateException
resides in java.lang package
and it is an unchecked exception since it is a child class of RuntimeException
.
Java docs for this exception state
Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
Scenarios
Practical examples for this exception would be
- Trying to launch a program when the computer restart is in progress.
- Attempting to start a car when it it already started.
- Trying to write to a socket which is closed.
- Adding a shutdown hook when a shutdown is in progress.
In short, IllegalStateException
should arise when performing an operation does not make any sense.
Examples in Java api
Following are some of the common places where an IllegalStateException
is thrown in java.
Collections
1. Calling remove()
on an empty iterator.
2. Trying to add element to a queue that is full.
3. Calling getKey()
and getValue()
on an entry that has been removed from the map.
4. Trying to modify the value of an element with iterator after removing that element.
Concurrency
1. Calling start()
on an already started thread or calling start()
more than once.
2. Thrown by forEach()
method of java.util.concurrent.ConcurrentMap
when an entry has been removed from the map.
Input/Output
1. Invoking methods such as next()
, nextLine()
, hasNext()
on a java scanner object after it is closed.
2. Reading token from StreamTokenizer
when reader is null
or there is no input to read.
3. Reading an entry from the zip when the zip has been closed.
& many more…
Suppose there is a list of objects and you want to convert this list to a map using java 8 streams. This can be done using below code.
Object[] obj1 = {1,"Object 1"}; Object[] obj2 = {2,"Object 2"}; Object[] obj3 = {3,"Object 3"}; List<Object[]> objects = List.of(obj1, obj2,obj3); Map<Object, Object> map = objects. stream(). collect( Collectors.toMap(obj->obj[0], obj -> obj[1]) );
In this example, there is a list whose each element is an Object
array. When this list is converted to a map, first element of list element becomes the key and second element becomes the value and the resultant map is
{1=Object 1, 2=Object 2, 3=Object 3}
So far so good.
But, if any two items of the list have same first element(which acts as the key in map), then toMap()
method will throw an IllegalStateException
.
Thus, if list elements are modified as
Object[] obj1 = {1,"Object 1"}; Object[] obj2 = {1,"Object 2"}; Object[] obj3 = {3,"Object 3"};
then toMap()
will throw below error
Exception in thread “main” java.lang.IllegalStateException: Duplicate key 1 (attempted merging values Object 1 and Object 2)
Resolving IllegalStateException
As clear from the discussion, this exception is caused by calling methods at the wrong place.
Thus, the first way is to ensure that the methods are invoked in appropriate context.
Secondly, the exception can be handled by enclosing the code that may result in IllegalStateException between try-catch
block.