Saturday, February 23, 2013

Runtime Exception in Java

Runtime Exceptions occur mostly due to some programming error, so as a programmer you need to be careful. Runtime exceptions (java.lang.RuntimeException) are unchecked; so compilers don't enforce you to handle them (either catch or throw). 

Below diagram shows the hierarchy of the Exception tree.


 

NullPointerException [api doc]

Thrown when an application attempts to use in null a case where an object is required. 

Below snippet throws NPE :

         String a = null;
         a.toString();

Java 7 adds a new utility class Objects [Java Doc];  Objects class has a method to perform the null check on an object.

           public foo(Bar bar){
                  this.bar = Objects.requireNonNull(bar);
           }

ClassCastException [api doc]

Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance.
        
Java allows you to cast one type to another provided they are compatible. And if the casting is done between two incompatible types (and compiler is unable to detect it); then you get this exception at Runtime. So this Exception is thrown when you try to downcast an object, but the actual type of class is not of that type. 

  1. Let's see below example:
          Object x = new Integer(0);
          System.out.println((String)x);
At compile time the type of x is Object, so x could be reference to String also (as Object is super class). But at execution time the type of x is Integer so its cast to String fails.  
    2.   Another case; you use code written before Java 1.5 with later version and mix Generics :

          List lll = new ArrayList();
          lll.add("sid");
          lll.add(2);
            
          Iterator<String> itr = lll.iterator();
          while(itr.hasNext()){
                System.out.println(" val "+ itr.next());  //Expects String only, but 2 is not
          } 

          String tmp = lll.get(1); //Throws ClassCastException; as type doesn't match

    3.   Casting an incompatible types
         
          class A {...}
          class B extends A {...}
          class C extends A {...}

          You can't cast a B to a C even though they're both of type A's.

IllegalArgumentException [api doc]

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

 This Exception is usually thrown if the arguments of a method are invalid. This way it fails at the earliest if the argument is invalid. This is usually not done for private methods; as class Author can ensure their validity. When argument check fails IllegalArgumentException, NullPointerException or IllegalStateException is thrown. 

   public class IllegalArgumentTest{
        public IllegalArgumentTest ( String name, double age ) {
            if ( name == null ) {
                throw new IllegalArgumentException("Name has no content.");
            }
            if ( age < 18.0f ) {
                 throw new IllegalArgumentException(" Person is not adult");
            }
            fname = name;
            fage = age;
        }
    //other methods..
  }
  You can document these exceptions in @throw clause of the method javadoc as they clearly state method requirement to the caller.

IllegalStateException [api doc]

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.

 This Exception is thrown in below situations:
  1. When you try to notify a thread that isn't in waiting state mode.
  2. When you try to run an already running thread. 
  3. When you try to call remove method twice while iterating a Collection (i.e. iterator.remove())
  4. ArrayBlockingQueue.add() throws this Exception if Queue is already full.

And Effective Java says (Item 60, page 248):
Another commonly reused exception is IllegalStateException. This is generally the exception to throw if the invocation is illegal because of the state of the receiving object. For example, this would be the exception to throw if the caller attempted to use some object before it had been properly initialized.

ConcurrentModificationException [api doc]

This exception may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible.
  1. Between creating an iterator and actually iterating the content you shouldn't modify the collection.        
            List<String> list = new ArrayList<String>();
            list.add("a1");
            list.add("a2");
           
            Iterator<String> iterator = list.iterator();
            list.add("a3");  //CME
           
            while(iterator.hasNext()){
                System.out.println(iterator.next());

            }         
  1.  Even if you try to modify list during iteration other than by using iteraot.remove(); you will get this exception.                                                                                                         
                 while(iterator.hasNext()){
                      System.out.println(iterator.next());
                      list.add("d1"); 
//CME

                     list.remove(0);  //CME
                }

UnsupportedOperationException [api doc]

Thrown to indicate that the requested operation is not supported. 

This is used by Collection framework to notify that a particular operation is not supported for the given Object.


        List<String> list = new ArrayList<String>();
        list.add("a1");
        list.add("a2");
       
        List<String> readList =  Collections.unmodifiableList(list);
        readList.add("a3");


Above snippet will throw UnsupportedOperationException because it's modifying a read only list.

CloneNotSupportedException [api doc]

Thrown to indicate that the clone method in class Object has been called to clone an object, but that the object's class does not implement the Cloneable interface.


No comments:

Post a Comment