Mega Code Archive

 
Categories / Java / Language Basics
 

Demonstrates exception chaining

// : c09:DynamicFields.java // A Class that dynamically adds fields to itself. // Demonstrates exception chaining. // {ThrowsException} // From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002 // www.BruceEckel.com. See copyright notice in CopyRight.txt. class DynamicFieldsException extends Exception { } public class DynamicFields {   private Object[][] fields;   public DynamicFields(int initialSize) {     fields = new Object[initialSize][2];     for (int i = 0; i < initialSize; i++)       fields[i] = new Object[] { null, null };   }   public String toString() {     StringBuffer result = new StringBuffer();     for (int i = 0; i < fields.length; i++) {       result.append(fields[i][0]);       result.append(": ");       result.append(fields[i][1]);       result.append("\n");     }     return result.toString();   }   private int hasField(String id) {     for (int i = 0; i < fields.length; i++)       if (id.equals(fields[i][0]))         return i;     return -1;   }   private int getFieldNumber(String id) throws NoSuchFieldException {     int fieldNum = hasField(id);     if (fieldNum == -1)       throw new NoSuchFieldException();     return fieldNum;   }   private int makeField(String id) {     for (int i = 0; i < fields.length; i++)       if (fields[i][0] == null) {         fields[i][0] = id;         return i;       }     // No empty fields. Add one:     Object[][] tmp = new Object[fields.length + 1][2];     for (int i = 0; i < fields.length; i++)       tmp[i] = fields[i];     for (int i = fields.length; i < tmp.length; i++)       tmp[i] = new Object[] { null, null };     fields = tmp;     // Reursive call with expanded fields:     return makeField(id);   }   public Object getField(String id) throws NoSuchFieldException {     return fields[getFieldNumber(id)][1];   }   public Object setField(String id, Object value)       throws DynamicFieldsException {     if (value == null) {       // Most exceptions don't have a "cause" constructor.       // In these cases you must use initCause(),       // available in all Throwable subclasses.       DynamicFieldsException dfe = new DynamicFieldsException();       dfe.initCause(new NullPointerException());       throw dfe;     }     int fieldNumber = hasField(id);     if (fieldNumber == -1)       fieldNumber = makeField(id);     Object result = null;     try {       result = getField(id); // Get old value     } catch (NoSuchFieldException e) {       // Use constructor that takes "cause":       throw new RuntimeException(e);     }     fields[fieldNumber][1] = value;     return result;   }   public static void main(String[] args) {     DynamicFields df = new DynamicFields(3);     System.out.println(df);     try {       df.setField("d", "A value for d");       df.setField("number", new Integer(47));       df.setField("number2", new Integer(48));       System.out.println(df);       df.setField("d", "A new value for d");       df.setField("number3", new Integer(11));       System.out.println(df);       System.out.println(df.getField("d"));       Object field = df.getField("a3"); // Exception     } catch (NoSuchFieldException e) {       throw new RuntimeException(e);     } catch (DynamicFieldsException e) {       throw new RuntimeException(e);     }   } } ///:~