Sunday 25 June 2017

2. Handle exceptions

1. How to handle Exceptions.
  1. Once Exception occurs in the program, we need to handle otherwise the program (thread/ flow) will be terminated.
  2. Five keywords are used in exception handling: try, catch, finally, throws and throw (take note that there is a difference between throw and throws).
  3. Java’s exception handling consists of three operations:
  1. Declaring exceptions
  2. Throwing an exception
  3. Catching an exception.
2. How to catch an Exceptions.
  1. Once Exception occurs in the program, we need to handle otherwise the program (thread) will be terminated.
  2. We need to use try-catch block for exception handling.
  3. Syntax of try-catch follows
try {
  // main logic, uses methods that may throw Exceptions
  ......
} catch (Exception1 ex) {
  // error handler for Exception1
  ......
} catch (Exception2 ex) {
  // error handler for Exception2
  ......
} finally {   // finally is optional
  // clean up codes, always executed regardless of exceptions
  ......
}
  1. Try block contains the main logic to execute, if any exception occurs in the code of try block then jvm creates exception object and throws that object from try block, remaining code will not execute.
  2. Catch block will catch that exception object and executes the catch block code.
  3. After executing catch block, finally block will execute.
  4. If no exception occurs during the running of the try-block, all the catch-blocks are skipped, and finally-block will be executed after the try-block.
  5. If one of the statements in the try-block throws an exception, the Java runtime ignores the rest of the statements in the try-block, and begins searching for a matching exception handler.
  6. It matches the exception type with each of the catch-blocks sequentially. If a catch-block catches that exception class or catches a superclass of that exception, the statement in that catch-block will be executed.
  7. The statements in the finally-block are then executed after that catch-block.
  8. The program continues into the next statement after the try-catch-finally, unless it is pre-maturely terminated or branch-out.
  9. If none of the catch-block matches, the exception will be passed up the call stack.
  10. The current method executes the finally clause (if any) and popped off the call stack. The caller follows the same procedures to handle the exception.
  11. The finally block is almost certain to be executed, regardless of whether or not exception occurs (unless JVM encountered a severe error or a System.exit() is called in the catch block).
3. Try-catch block rules.
  1. A try-block must be accompanied by at least one catch-block or a finally-block.
  2. You can have multiple catch-blocks. Each catch-block catches only one type of exception.
  3. A catch block requires one argument, which is a throwable object (i.e., a subclass of java.lang.Throwable), as follows:
catch (AThrowableSubClass aThrowableObject) {
  // exception handling codes
}
  1. You can use the following methods to retrieve the type of the exception and the state of the program from the Throwable object.
    1. printStackTrace()
try {
  Scanner in = new Scanner(new File("test.in"));
  // process the file here
  ......
} catch (FileNotFoundException ex) {
  ex.printStackTrace();
}
    1. We can also use printStackTrace(PrintStream s) or printStackTrace(PrintWriter s).
    2. getMessage(): Returns the message specified if the object is constructed using constructor Throwable(String message).
    3. toString(): Returns a short description of this Throwable object, consists of the name of the class, a colon ':', and a message from getMessage().
  1. A catch block catching a specific exception class can also catch its subclasses.
  2. Hence, catch(Exception ex) {...} catches all kinds of exceptions.
  3. However, this is not a good practice as the exception handler that is too general may unintentionally catches some subclasses' exceptions it does not intend to.
  4. The order of catch-blocks is important. A subclass must be caught (and placed in front) before its superclass. Otherwise, you receive a compilation error "exception XxxException has already been caught".
try {
  Scanner in = new Scanner(new File("test.in"));
  // process the file here
  ......
} catch (Exception ex) {
  ex.printStackTrace();
}
catch (FileNotFoundException ex) {
  ex.printStackTrace();
}
  1. The finally-block is meant for cleanup code such as closing the file, database connection regardless of whether the try block succeeds. The finally block is always executed (unless the catch-block pre-maturely terminated the current method).
4. Can we write try block without catch block
  1. Yes, we can write any below combination of blocks.
    1. try-catch
    2. try-finally
    3. try-catch-finally
5. What is a Throwing an exception
  1. By default, if any error or exception occurs in the code, JVM create an exception object and throws the exception object.
  2. But if we want we can also create our own exception object and throws that object.
  3. For example, If user enters -ve age value, we can throw an exception explicitly.
  4. By using ‘throw’ keyword, we can throw an exception.
  5. At a time we can throw one exception only.
public void methodD() throws XxxException, YyyException {   // method's signature
  // method's body
  ...
  ...
  // XxxException occurs
  if ( ... )
     throw new XxxException(...);   // construct an XxxException object and throw to JVM
  ...
  // YyyException occurs
  if ( ... )
     throw new YyyException(...);   // construct an YyyException object and throw to JVM
  ...
}
  1. Note that the keyword to declare exception in the method's signature is "throws" and the keyword to throw an exception object within the method's body is "throw".
  2. ‘throws’ keyword is giving a notification to compiler about the current method may throws an exception.
public class MethodCallStackDemo {
  public static void main(String[] args) {
     System.out.println("Enter main()");
     methodA();
     System.out.println("Exit main()");
  }

  public static void methodA() {
     System.out.println("Enter methodA()");
     try{
        methodB();
     }catch(Exception e){....}
     System.out.println("Exit methodA()");
  }

  public static void methodB() throws Exception{
     System.out.println("Enter methodB()");
     methodC();
     System.out.println("Exit methodB()");
  }

  public static void methodC() throws Exception{
     System.out.println("Enter methodC()");
     System.out.println("Exit methodC()");
  }
}

6. How Exception handling will work?

  1. When an error occurs within a method, the method creates an object and hands it off to the runtime system.
  2. The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred.
  3. Creating an exception object and handing it to the runtime system is called throwing an exception.
  4. After a method throws an exception, the runtime system attempts to find something to handle it.
  5. The set of possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred.The list of methods is known as the call stack (see the next figure)
                                                   
  6. The runtime system searches the call stack for a method that contains a block of code that can handle the exception.
  7. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called.
  8. When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.
  9. The exception handler chosen is said to catch the exception.
  10. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, as shown in the next figure, the runtime system (and, consequently, the program) terminates.
                           

1. Introduction to Exception handling

1. What is an Exception?
  1. An exception is an abnormal event that arises during the execution of the program and disrupts the normal flow of the program.
  2. Exception will arise when user enters invalid input, loss of resources.
  3. If these exceptions are not handled properly, the program terminates abruptly and may cause severe consequences.
  4. For example, the network connections, database connections and files may remain opened; database and file records may be left in an inconsistent state.
  5. Java has a built-in mechanism for handling runtime errors, referred to as exception handling.
  6. This is to ensure that you can write robust programs for mission-critical applications.

2. Drawbacks of exception handling in ‘C’ language.
  1. The programmers are not made to aware of the exceptional conditions.
  2. For example, the file to be opened may not necessarily exist. The programmer therefore did not write codes to test whether the file exists before opening the file.
  3. Suppose the programmer is aware of the exceptional conditions, he/she might decide to finish the main logic first, and write the exception handling codes later – this "later", unfortunately, usually never happens. In other words, you are not force to write the exception handling codes together with the main logic.
  4. Suppose the programmer decided to write the exception handling codes, the exception handling codes intertwine with the main logic in many if-else statements. This makes main logic hard to follow and the entire program hard to read. For example,

if (file exists) {
  open file;
  while (there is more records to be processed) {
     if (no IO errors) {
        process the file record
     } else {
        handle the errors
     }
  }
  if (file is opened) close the file;
} else {
  report the file does not exist;
}
3. How Java overcomes these drawbacks of ‘c’ language exception handling.
  1. You will be informed of the exceptional conditions that may arise in calling a method - Exceptions are declared in the method's signature.
  2. You are forced to handle exceptions while writing the main logic and cannot leave them as an afterthought - Your program cannot compiled without the exception handling codes.
  3. Exception handling codes are separated from the main logic - Via the try-catch-finally construct.
readFile {
   try {
       open the file;
       determine its size;
       allocate that much memory;
       read the file into memory;
       close the file;
   } catch (fileOpenFailed) {
      doSomething;
   } catch (sizeDeterminationFailed) {
       doSomething;
   } catch (memoryAllocationFailed) {
       doSomething;
   } catch (readFailed) {
       doSomething;
   } catch (fileCloseFailed) {
       doSomething;
   }
}

4. What is method call stack?
  1. A typical application involves many levels of method calls, which is managed by a so-called method call stack.
  2. A stack is a last-in-first-out queue. In the following example, main() method invokes methodA(); methodA() calls methodB(); methodB() calls methodC().
public class MethodCallStackDemo {
  public static void main(String[] args) {
     System.out.println("Enter main()");
     methodA();
     System.out.println("Exit main()");
  }

  public static void methodA() {
     System.out.println("Enter methodA()");
     methodB();
     System.out.println("Exit methodA()");
  }

  public static void methodB() {
     System.out.println("Enter methodB()");
     methodC();
     System.out.println("Exit methodB()");
  }

  public static void methodC() {
     System.out.println("Enter methodC()");
     System.out.println("Exit methodC()");
  }
}

Output :
Enter main()
Enter methodA()
Enter methodB()
Enter methodC()
Exit methodC()
Exit methodB()
Exit methodA()
Exit main()

  1. Flow of execution is
    1. JVM invoke the main().
    2. main() pushed onto call stack, before invoking methodA().
    3. methodA() pushed onto call stack, before invoking methodB().
    4. methodB() pushed onto call stack, before invoking methodC().
    5. methodC() completes.
    6. methodB() popped out from call stack and completes.
    7. methodA() popped out from the call stack and completes.
    8. main() popped out from the call stack and completes. Program exits.
                                   
5. How an Exception will occur in a program, default how it will print in console.
  1. When user enters an invalid input it may cause exception.
public class MethodCallStackDemo {
  public static void main(String[] args) {
     System.out.println("Enter main()");
     methodA();
     System.out.println("Exit main()");
  }

  public static void methodA() {
     System.out.println("Enter methodA()");
     methodB();
     System.out.println("Exit methodA()");
  }

  public static void methodB() {
     System.out.println("Enter methodB()");
     methodC();
     System.out.println("Exit methodB()");
  }

  public static void methodC() {
     System.out.println("Enter methodC()");
 System.out.println(1/0);//divide-by-0 trigger an ArithmeticException
     System.out.println("Exit methodC()");
  }
}
Output :
Enter main()
Enter methodA()
Enter methodB()
Enter methodC()
Exception in thread "main" java.lang.ArithmeticException: / by zero
       at MethodCallStackDemo.methodC(MethodCallStackDemo.java:22)
       at MethodCallStackDemo.methodB(MethodCallStackDemo.java:16)
       at MethodCallStackDemo.methodA(MethodCallStackDemo.java:10)
       at MethodCallStackDemo.main(MethodCallStackDemo.java:4)




3. Java Program to create Binary Tree