Exception Handling Tips

By | March 19, 2016 | 123 Views

Please refer to Basic Exception Handling before reading some exception questions below.

Question 1.  Consider the following program:

import java.lang.*;

class InvalidValueException extends IllegalArgumentException {}

class InvalidKeyException extends IllegalArgumentException {}

class BaseClass {
   void foo() throws IllegalArgumentException {
      throw new IllegalArgumentException();
   }
}

class DeriClass extends BaseClass {
   public void foo() throws IllegalArgumentException {
      throw new InvalidValueException();
   }
}

class DeriDeriClass extends DeriClass {
   public void foo() { // LINE A
      throw new InvalidKeyException();
   }
}

class Test {
   public static void main(String []args) {
      try {
         BaseClass base = new DeriDeriClass();
         base.foo();
      } catch(RuntimeException e) {
         System.out.println(e);
      }
   }
}

Which one of the following options correctly describes the behavior of this program?
a) The program prints the following: InvalidKeyException.
b) The program prints the following: RuntimeException.
c) The program prints the following: IllegalArgumentException.
d) The program prints the following: InvalidValueException.
e) When compiled, the program will result in a compiler error in line marked with comment Line A due to missing throws clause.

Tips: It is not necessary to provide an Exception thrown by a method when the method is overriding a method defined with an exception (using the throws clause). Thus, the given program will compile successfully.

Question 2.  Consider the following program:

class ExceptionBehavior {
   public static void main(String []args) {
      try {
         int i = 100/0; // LINE A
         System.out.print("after throw -> ");
      } catch(ArithmeticException ae) {
         System.out.print("in catch -> ");
         return;
      } finally {
         System.out.print("in finally -> ");
      }
      System.out.print("after everything");
   }
}

Which one of the following options best describes the behavior of this program?
a) The program prints the following: in catch -> in finally -> after everything.
b) The program prints the following: after throw -> in catch -> in finally -> after everything.
c) The program prints the following: in catch -> in finally -> after everything.
d) The program prints the following: in catch -> after everything.
e) The program prints the following: in catch -> in finally ->.
f) When compiled, the program results in a compiler error in line marked with comment in LINE A for divide-by-zero.

Tips: The statement println(“after throw -> “); will never be executed since the line marked with the comment LINE A throws an exception. The catch handles ArithmeticException, so println(“in catch -> “); will be executed. Following that, there is a return statement, so the function returns. But before the function returns, the finally statement should be called, so the statement println(“in finally -> “); will get executed. Thus, the statement println(“after everything”); will never get executed.

Question 3.  Consider the following program:

public class Animal {
	public void eat() throws Exception {
		// Throw an exception
	}
}
public class Dog extends Animal{	
	public void eat(){ /* No exception*/}
	public static void main(String[] args) {
		Animal a = new Dog();
		Dog d = new Dog();
		d.eat();
		a.eat();
	}
}

Which one of the following options best describes the behavior of this program?
a) The program will compile successfully.
b) The program will not compile because of the Exception (Run-time) declared on the Animal eat() method.
c) The program will not compile because of the Exception on Dog eat() method.

Tips: If a method is overridden but you use a polymorphic (super-type) reference to refer to the sub-type object with the overriding method, the compiler assumes that your are calling the super-type version of the method. If the supertype version declares a checked exception, but the overriding subtype method does not, the compiler still think that your are now calling a method that declares a exception. The d.eat() method used would be the Dog version, which does not declare the exception. a.eat() method used the Animal version that requires handling exception. At Line 12, the program will throw a Runtime exception. Fixed by add try/catch or throw Exception in main method.

Question 4.  Consider the following program:

import java.io.IOException;
public class Animal {
	public void eat() throws IOException {
		// Throw an IOException
	}
}
import java.io.FileNotFoundException;
import java.io.IOException;

public class Dog extends Animal{	
	public void eat() throws Exception{ } // METHOD A
	public void eat(String s) throws Exception {};
	public void eat() throws  FileNotFoundException { //METHOD B
                // FileNotFoundExection is a subclass of IOException.
		System.out.print("FileNotFoundException ");
	};
	public static void main(String[] args) throws Exception {
		Animal a = new Dog();
		Dog d = new Dog();		
		d.eat();
		a.eat();
	}
}

Which the following options best describes the behavior of this program?
a) The program will have Runtime Exception: Exception Exception is not compatible with throws clause in Animal.eat() and Duplicate method eat() in type Dog.
b) If the METHOD B is removed, the program will throw a run-time exception: Exception Exception is not compatible with throws clause in Animal.eat().
c) If the METHOD A is removed, both the d.eat and a.eat method will call METHOD B and print out: FileNotFoundException FileNotFoundException .
d) None above.

Tips: The overriding method MUST not throw new or broader checked exceptions. It should throw fewer or narrower checked exceptions, or any unchecked exception.

Question 5.  Consider the following program:

public class Foo {
	public void doStuff(int y, String s){};
}
import java.io.IOException;

public class Bar extends Foo{
	public void doStuff(int y, long s) throws IOException{};
	
	public static void main(String[] args) {
		Foo f1 = new Foo();
		Foo f2 = new Bar();
		Bar b = new Bar();
		f1.doStuff(1, "String");
		f1.doStuff(1, 2);                //LINE A
		f2.doStuff(1, "String");         //LINE B
		f2.doStuff(1, 2);                //LINE C
		b.doStuff(1, 2);                 //LINE D
		b.doStuff(1, "String");          //LINE E
		((Bar)f1).doStuff(1, "String");  //LINE F
		((Bar)f1).doStuff(1, 2);         //LINE G
	}
}

Which the following options best describes the behavior of this program?
a) The program has Runtime Exception at LINE A & C: The method doStuff(int, String) in the type Foo is not applicable for the arguments (int, int).
b) If LINE A and C are removed, the program still throws Runtime Exception at LINE D, G: Unhandled exception type IOException.
c) If adding main(String[] args) throws IOException, the program will throw a compiler exception at LINE F, and LINE G : Foo cannot be cast to Bar
d) The program will compile without any issue if removing LINE A, C, F, G as well as adding main(String[] args) throws IOException.

Tips:
a) The Foo f1, f2 will call its methods declared in Food super class.
b) LINE D, G will call doStuff method with Exception of Bar subclass. So the exception need to be handled via throws/try-catch.
c) Compiler must allow to work at runtime because compiler knows f1 is really referring to a Bar object, so it’s okay to make a new Bar reference variable to refer to that object. However, the compilation will fail because the compiler only verifies the Bar and Foo are in the same inheritance tree, so that it is possible to check that f1 is of type Bar when we do downcast. Add if(f1 instanceof Bar){ /*LINE F, G*/ } is safe.
d) LINE D is not overridden, Subclass Bar overloads the doStuff () method, by varying the argument list, so the IOException is fine.

Leave a Reply

Your email address will not be published. Required fields are marked *