Exception Handling Java Interview Questions – Set 01

What is the difference between checked and unchecked exceptions?

In general, unchecked exceptions represent defects in the program (bugs), which are normally Runtime exceptions.

Furthermore, checked exceptions represent invalid conditions in areas outside the immediate control of the program.

Explain Checked Exceptions and Unchecked Exceptions with examples

Unchecked exceptions :

represent defects in the program (bugs) – often invalid arguments passed to a non-private method. To quote from The Java Programming Language, by Gosling, Arnold, and Holmes : “Unchecked runtime exceptions represent conditions that, generally speaking, reflect errors in your program’s logic and cannot be reasonably recovered from at run time.”

are subclasses of RuntimeException, and are usually implemented using IllegalArgumentException, NullPointerException, or IllegalStateException

a method is not obliged to establish a policy for the unchecked exceptions thrown by its implementation (and they almost always do not do so)

Checked exceptions :

represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files)

are subclasses of Exception

a method is obliged to establish a policy for all checked exceptions thrown by its implementation (either pass the checked exception further up the stack, or handle it somehow)

It is somewhat confusing, but note as well that RuntimeException (unchecked) is itself a subclass of Exception (checked).

Example 1

Model Objects are the data-centric classes used to represent items in a particular domain. Model Object constructors need to handle both arbitrary user input, and input from underlying database ResultSets.

Model Object constructors should throw checked exceptions:

the program may have no direct control over user input. This is particularly true in web applications. It seems safest for a Model Object to treat user input as having arbitrary, unvalidated content.

it is not safe for an application to make any assumptions about the state of the database. The database is an independent entity, and its data may be changed by various means, outside of any particular application. For example, data load tools are commonly used to create an initial state for a new database. Such data can easily violate the constraints built into a calling application. Thus, the safest assumption is to treat database ResultSets as having arbitrary, unvalidated content.

Here is an example Model Object, taken from the WEB4J example application. Its constructor throws ModelCtorException (a checked exception) :

package hirondelle.fish.main.resto;

import hirondelle.web4j.model.ModelCtorException;

import hirondelle.web4j.model.ModelUtil;

import hirondelle.web4j.model.Id;

import hirondelle.web4j.security.SafeText;

import hirondelle.web4j.model.Decimal;

import static hirondelle.web4j.model.Decimal.ZERO;

import hirondelle.web4j.model.Check;

import hirondelle.web4j.model.Validator;

import static hirondelle.web4j.util.Consts.FAILS;

/** Model Object for a Restaurant. */

public final class Resto {

/**

Full constructor.

@param aId underlying database internal identifier (optional) 1..50 characters

@param aName of the restaurant (required), 2..50 characters

@param aLocation street address of the restaurant (optional), 2..50 characters

@param aPrice of the fish and chips meal (optional) $0.00..$100.00

@param aComment on the restaurant in general (optional) 2..50 characters

*/

public Resto(

Id aId, SafeText aName, SafeText aLocation, Decimal aPrice, SafeText aComment

) throws ModelCtorException {

fId = aId;

fName = aName;

fLocation = aLocation;

fPrice = aPrice;

fComment = aComment;

validateState();

}

public Id getId() { return fId; }

public SafeText getName() {  return fName; }

public SafeText getLocation() {  return fLocation;  }

public Decimal getPrice() { return fPrice; }

public SafeText getComment() {  return fComment; }

@Override public String toString(){

return ModelUtil.toStringFor(this);

}

@Override public  boolean equals(Object aThat){

Boolean result = ModelUtil.quickEquals(this, aThat);

if ( result ==  null ) {

Resto that = (Resto) aThat;

result = ModelUtil.equalsFor(

this.getSignificantFields(), that.getSignificantFields()

);

}

return result;

}

@Override public int hashCode(){

if ( fHashCode == 0 ){

fHashCode = ModelUtil.hashCodeFor(getSignificantFields());

}

return fHashCode;

}

// PRIVATE //

private final Id fId;

private final SafeText fName;

private final SafeText fLocation;

private final Decimal fPrice;

private final SafeText fComment;

private int fHashCode;

private static final Decimal HUNDRED = Decimal.from(“100”);

private void validateState() throws ModelCtorException {

ModelCtorException ex = new ModelCtorException();

if ( FAILS == Check.optional(fId, Check.range(1,50)) ) {

ex.add(“Id is optional, 1..50 chars.”);

}

if ( FAILS == Check.required(fName, Check.range(2,50)) ) {

ex.add(“Restaurant Name is required, 2..50 chars.”);

}

if ( FAILS == Check.optional(fLocation, Check.range(2,50)) ) {

ex.add(“Location is optional, 2..50 chars.”);

}

Validator[] priceChecks = {Check.range(ZERO, HUNDRED), Check.numDecimalsAlways(2)};

if ( FAILS == Check.optional(fPrice, priceChecks)) {

ex.add(“Price is optional, 0.00 to 100.00.”);

}

if ( FAILS == Check.optional(fComment, Check.range(2,50))) {

ex.add(“Comment is optional, 2..50 chars.”);

}

if ( ! ex.isEmpty() ) throw ex;

}

private Object[] getSignificantFields(){

return new Object[] {fName, fLocation, fPrice, fComment};

}

}

Example 2

Args is a convenient utility class. It performs common validations on method arguments. If a validation fails, then it throws an unchecked exception. It is suitable for checking the internal consistency of program, but not for checking arbitrary user input.

package hirondelle.web4j.util;

import java.util.regex.*;

/**

Utility methods for common argument validations.

<P>Replaces <tt>if</tt> statements at the start of a method with

more compact method calls.

<P>Example use case.

<P>Instead of :

<PRE>

public void doThis(String aText){

if (!Util.textHasContent(aText)){

throw new IllegalArgumentException();

}

//..main body elided

}

</PRE>

<P>One may instead write :

<PRE>

public void doThis(String aText){

Args.checkForContent(aText);

//..main body elided

}

</PRE>

*/

public final class Args {

/**

If <code>aText</code> does not satisfy {@link Util#textHasContent}, then

throw an <code>IllegalArgumentException</code>.

<P>Most text used in an application is meaningful only if it has visible content.

*/

public static void checkForContent(String aText){

if( ! Util.textHasContent(aText) ){

throw new IllegalArgumentException(“Text has no visible content”);

}

}

/**

If {@link Util#isInRange} returns <code>false</code>, then

throw an <code>IllegalArgumentException</code>.

@param aLow is less than or equal to <code>aHigh</code>.

*/

public static void checkForRange( int aNumber, int aLow, int aHigh ) {

if ( ! Util.isInRange(aNumber, aLow, aHigh) ) {

throw new IllegalArgumentException(aNumber + ” not in range ” + aLow + “..” + aHigh);

}

}

/**

If <tt>aNumber</tt> is less than <tt>1</tt>, then throw an

<tt>IllegalArgumentException</tt>.

*/

public static void checkForPositive(int aNumber) {

if (aNumber < 1) {

throw new IllegalArgumentException(aNumber + ” is less than 1″);

}

}

/**

If {@link Util#matches} returns <tt>false</tt>, then

throw an <code>IllegalArgumentException</code>.

*/

public static void checkForMatch(Pattern aPattern, String aText){

if ( ! Util.matches(aPattern, aText) ){

throw new IllegalArgumentException(

“Text ” + Util.quote(aText) + ” does not match ‘” +aPattern.pattern()+ “‘”

);

}

}

/**

If <code>aObject</code> is null, then throw a <code>NullPointerException</code>.

<P>Use cases :

<pre>

doSomething( Football aBall ){

//1. call some method on the argument :

//if aBall is null, then exception is automatically thrown, so

//there is no need for an explicit check for null.

aBall.inflate();

//2. assign to a corresponding field (common in constructors):

//if aBall is null, no exception is immediately thrown, so

//an explicit check for null may be useful here

Args.checkForNull( aBall );

fBall = aBall;

//3. pass on to some other method as parameter :

//it may or may not be appropriate to have an explicit check

//for null here, according the needs of the problem

Args.checkForNull( aBall ); //??

fReferee.verify( aBall );

}

</pre>

*/

public static void checkForNull(Object aObject) {

if ( aObject == null ) {

throw new NullPointerException();

}

}

// PRIVATE //

private Args(){

//empty – prevent construction

}

Is there anything wrong with the above code?

Yes, 2 things — firstly, the above sort is case sensitive, that is the uppercase takes priority over lowercase pushing ‘Java’ after ‘JSP’. Secondly, if the collection had any null values, it will throw a NullpointerException.

These two issues can be rectified by providing a custom sorting implementation that ignores case and handles null values by pushing them to the end. The Collections class’s sort method takes a Comparator implementation as a second argument. In the code below, the Comparator has been implemented as an anonymous inner class. The compare(…) method will be called a number of times by the Collections.sort(list, comparator).

import java.util.Arrays;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class Sort2 {

public static void main(String[] args) {

List<String> values = Arrays.asList(“JEE”, “Java”, null,  “Servlets”, null, “JMS”, “JNDI”, “JDBC”, “JSP”, null,”EJB”);

//The comparator is defined as an anonymous inner class, but it can be

//defined in its own class. Handles nulls and ignores case

Collections.sort(values, new Comparator<String>() {

@Override

public int compare(String o1, String o2) {

//push the null values to the end

if(o1 == null){

if(o2 == null) {

return 0;

}

return 1;

}

else if(o2 == null){

return -1;

}

return o1.compareToIgnoreCase(o2);

}

}); // anonymous inner class end

System.out.println(values);

}

}

What are the differences between checked and unchecked exceptions?

A checked exception is any subclass of Exception (or Exception itself), excluding class RuntimeException and its subclasses.

Making an exception checked forces client programmers to deal with the possibility that the exception will be thrown. eg, IOException thrown by java.io.FileInputStream’s read() method

Unchecked exceptions are RuntimeException and any of its subclasses. Class Error and its subclasses also are unchecked.

With an unchecked exception, however, the compiler doesn’t force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. eg, StringIndexOutOfBoundsException thrown by String’s charAt() method.

Checked exceptions must be caught at compile time. Runtime exceptions do not need to be. Errors often cannot be, as they tend to be unrecoverable.

Can an exception be rethrown

Yes, an exception can be rethrown.

What is the purpose of the finally clause of a try-catch-finally statement

The finally clause is used to provide the capability to execute code no matter whether or not an exception is thrown or caught.

What is final, finalize() and finally?-

final : final keyword can be used for class, method and variables. A final class cannot be subclassed and it prevents other programmers from subclassing a secure class to invoke insecure methods. A final method can’t be overridden. A final variable can’t change from its initialized value. finalize() : finalize() method is used just before an object is destroyed and can be called just prior to garbage collection. finally : finally, a key word used in exception handling, creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block. The finally block will execute whether or not an exception is thrown. For example, if a method opens a file upon exit, then you will not want the code that closes the file to be bypassed by the exception-handling mechanism. This finally keyword is designed to address this contingency.

What is OutOfMemoryError in java? How to deal with java.lang.OutOfMemeryError error?

This Error is thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. Note: Its an Error (extends java.lang.Error) not Exception. Two important types of OutOfMemoryError are often encountered

  • lang.OutOfMemoryError: Java heap space
    • The quick solution is to add these flags to JVM command line when Java runtime is started:
      • -Xms1024m -Xmx1024m
    • lang.OutOfMemoryError: PermGen space
      • The solution is to add these flags to JVM command line when Java runtime is started:
        • -XX:+CMSClassUnloadingEnabled
        • -XX:+CMSPermGenSweepingEnabled

Long Term Solution: Increasing the Start/Max Heap size or changing Garbage Collection options may not always be a long term solution for your Out Of Memory Error problem. Best approach is to understand the memory needs of your program and ensure it uses memory wisely and does not have leaks. You can use a Java memory profiler to determine what methods in your program are allocating large number of objects and then determine if there is a way to make sure they are no longer referenced, or to not allocate them in the first place.

Which arithmetic operations can result in the throwing of an ArithmeticException

Integer / and % can result in the throwing of an ArithmeticException.

What is the use of the finally block? Is finally block in Java guaranteed to be called? When finally block is NOT called?

Finally is the block of code that executes always. The code in finally block will execute even if an exception is occurred. Finally block is NOT called in following conditions

  • If the JVM exits while the try or catch code is being executed, then the finally block may not execute. This may happen due to System.exit() call.
  • if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
  • If a exception is thrown in finally block and not handled then remaining code in finally block may not be executed.

What classes of exceptions may be thrown by a throw statement

A throw statement may throw any expression that may be assigned to the Throwable type.