Title: IO: Checked Exceptions
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

I/O: Checked Exceptions

1. File I/O using Scanner and PrintStream


import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Scanner;


public class FileIO {

    int[] readNumbers(int num)
    {
        int[] arr = new int[num];
        Scanner keyboard = new Scanner(System.in);
        for (int i=0; i < num; i++)
        {
            arr[i] = keyboard.nextInt();
        }
        return arr;
    }


    int[] readNumbers(int num, String filename)
    {
        int[] arr = new int[num];
        File f = new File(filename);

// In the video, the "input" variable was called keyboard (which is dumb)
        Scanner input = null;
        try {
            input = new Scanner(f);
        } catch (FileNotFoundException e) {
            System.out.println("Error" + e);
            e.printStackTrace();
        }
        for (int i=0; i < num; i++)
        {
            arr[i] = input.nextInt();
        }
        input.close();
        return arr;
    }
    void printNumbers(int[] arr)
    {
        for (int i=0; i < arr.length; i++)
            System.out.println(arr[i]);
    }

    void printNumbers(int[] arr, String filename)
    {
        PrintStream ps =null;
        try {
            ps = new PrintStream(filename);
        } catch (FileNotFoundException e) {
            System.out.println("Error: "+e);
            e.printStackTrace();
        }
        for (int i=0; i < arr.length; i++)
            ps.println(arr[i]);

        ps.close();
    }
    public static void main(String[] args) {
        FileIO fio = new FileIO();
        int[] arr = fio.readNumbers(5);
        fio.printNumbers(arr);


        arr = fio.readNumbers(5, "temp.txt");
        fio.printNumbers(arr, "temp.txt");


    }

}



2. Throwable class - the parent class of all exceptions is in the java.lang package and is called Throwable. Throwable is derived from (you guessed it) Object.
  - The Throwable class has useful methods (see the Throwable class in package java.lang for details):
    - getMessage - returns information stored in the Throwable class
    - printStackTrace - prints out a list of all of the routines in the program calling stack.
Try adding the following code in the catch clause of the readCarefully routine in the previous example:


System.out.println("Error = " + e);
e.printStackTrace();


  - Classes Derived from Throwable
    - Error - If you get an Error exception, there isn't much you can do. In this case the Java Run Time system is either crashed or out of resources. I'm not sure I have every generated Error Exceptions.
    - Exception - Most of your exceptions will be derived from the Exception class. Unless your class is derived from RuntimeException, the compiler will force you to deal with any exception that can be thrown.
  - Children of Exception - There are many classes derived from Exception. In fact there is a large tree of classes derived from Exception. Take a look at the Exception tree of classes in Online help . There is one significant subtree worth mentioning:
RuntimeException - RuntimeException is derived from Exception. All RuntimeExceptions and all classes derived from RuntimeExceptions have a unique property. Java does not force you to deal with RuntimeExceptions. This means that try ... catch logic is optional for RuntimeExceptions. Sometimes this is referred to as UNCHECKED Exceptions

  - NON RuntimeException - Java forces you to deal with all Exceptions that are not part of the RuntimeException subtree. These Exceptions are sometimes called CHECKED Exceptions. This means that either you surround the logic which can generate the exception with try ... catch logic or you "duck" the exception issue by adding to your method definition:
throws xyzException
"ducking" ramafications - If a method "ducks" an exception, then it's up to the calling method to process the exception. Of course the calling method can also "duck" an exception the same way used by the original method. If the main method "ducks" the exception, then the program aborts and the java program itself prints out the exception. You have probably already hit this case already by mistake.
3. Rework the previous example to completely "Duck" the exceptions
4. Ants Game of life code (In the video we show throwing an exception in the constructor to the game of Life:


package simple_ant;

import java.util.*;

class MyException extends RuntimeException
{
 double density;
	MyException(double density)
	{
	    super ("Bad Density: "+ density);
	    this.density = density;
	}
}



public class Life {
    static Scanner keyboard = new Scanner(System.in);
    static final int NUM_ROWS = 8;
    static final int NUM_COLS = 10;
    Ant[][] world = new Ant[NUM_ROWS][NUM_COLS];

    public static void main(String[] args)
    {
        System.out.println("Enter in Ant density (number between 0.0 and 1.0)");
        double density = keyboard.nextDouble();
        Life life;
        try {
            life = new Life(density);
            life.playGame(true);
        } catch (MyException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            System.out.println("Caught a MyException: density = "+ e.density);
        }

    }

    public Life(double density)
    {
        if (density <= 0.0  || density >= 1.0)
            throw new MyException(density);
        for (int i= 0; i< NUM_ROWS; i++)
            for (int j=0; j < NUM_COLS; j++)
            {
                world[i][j] = new Ant();
                if (Math.random() < density)
                    world[i][j].setAlive(true);
            }
    }
    void display()
    {
        for (int c=0; c < NUM_COLS; c++)
        {
            if (c > 0) System.out.printf("%2d ",c);
            else System.out.print("    0 ");
        }
        System.out.println();

        for (int r=0; r < NUM_ROWS; r++)
        {
            System.out.printf("%2d ", r);

            for (int c=0; c < NUM_COLS; c++)
            {
                System.out.print(world[r][c]);
            }
            System.out.println();
        }
    }
    int countNeighbors(int row, int col)
    {
        int count=0;
        for (int r=row-1; r <= row+1; r++)
            for (int c=col-1; c <= col+1; c++)
            {
                if (r==row && c==col)continue; //Cell itself
                if (r<0 || c <0) continue; // Out bounds on top or left
                if (r>=NUM_ROWS || c >=NUM_COLS)continue; // Out of bounds on bottom or right
                if (world[r][c].isAlive())
                    count+=1;
            }
        return count;
    }
    void worldUpdate(boolean debug)
    {
        for (int i= 0; i< NUM_ROWS; i++)
            for (int j=0; j < NUM_COLS; j++)
            {
                int count = countNeighbors(i,j);
                world[i][j].update(count, i, j, debug);
            }
    }
    void playGame(boolean debug)
    {
        String response=null;
        do
        {
            display();
            worldUpdate(debug);
            System.out.println("Do you want to keep going (y/n)?");
            response = keyboard.next();
        } while (response.charAt(0)=='y');
    }



}

// *******************************************************************
// *******************************************************************

package simple_ant;
public class Ant {
    static final int ISOLATION_DEATH_COUNT =2;
    private boolean alive=false;
    private int isolationCount=0;

    public void setAlive(boolean setVal)
    {
        alive = setVal;
    }
    public boolean isAlive()
    {
        return alive;
    }
    public String toString()
    {
        if (alive) return " A ";
        else       return "   ";
    }
    void update(int numNeighbors, int row, int col, boolean debug)
    {
        if (alive)
        {
            if (numNeighbors > 3)
            {
                // We die of crowding
                alive = false;
                if (debug)System.out.println(row+":"+col +" - Die due to crowding");
                return;
            }
            if (numNeighbors == 0)
            {
                if (++isolationCount >= 2)
                {
                    // We die of isolation
                    alive = false;
                    if (debug)System.out.println(row+":"+col +" - Die due to isolation");
                    return;
                }
            }
            else
                isolationCount = 0;
        }
        else
        { // Not a live cell -- see if we can birth an Ant
            if (numNeighbors == 2)
            {
                alive = true;
                if (debug)System.out.println(row+":"+col +" - Birth");
            }
        }


    }


}





********* The following related examples don't show up on the video
5. Throwing exceptions - You can throw any exception that is defined with a command like:
throw new Exception("I found an error");
OR
throw new RuntimeException("An Unchecked error: optional try ... catch");
OR
throw new FileNotFoundException("Couldn't find my favorite file");
Here is a sample program that throws an exception that is nested in several calls of routines. The actual exception gets caught in the main routine.

  public class ExceptionMethods {
  static void firstLevel() throws Exception
  {
      secondLevel();
  }
  static void secondLevel() throws Exception
  {
      thirdLevel();
  }
  static void thirdLevel() throws Exception
  {
      throw new Exception("Here's my Exception");
  }

  public static void main(String[] args) {
    try {
      firstLevel();
    }
    catch(Exception e) {
      System.out.println("caught:" + e);
      e.printStackTrace();
    }
  }
}


6. Creating your own Exception class:


  class MyException extends Exception
  {
      ....
       MyException(String info, Date time)
	   {
	      ....
	   }
  }

  throw new MyException("Error just found", new Date());



7. Rethrowing an Exception - An exception handler can decide to rethrow an exception that it is currently processing:

  public class Rethrowing {
  public static void f() throws Exception {
    System.out.println("f() -- throw exception");
    throw new Exception("thrown from f()");
  }
  public static void g() throws Throwable {
    try
    {
      f();
    }
    catch(Exception e) {
      System.out.println("g() -- stack dump");
      e.printStackTrace();
      System.out.println("rethrowing Exception in g");
      throw e;
    }
  }
  public static void
  main(String[] args) throws Throwable {
    try {
      g();
    }
    catch(Exception e) {
      System.out.println("Caught in main" + e);
      e.printStackTrace();
    }
  }
}



Last Updated: Dec 3, 2012