OnJava8-Examples/exceptions/DynamicFields.java

121 lines
3.5 KiB
Java
Raw Normal View History

2015-09-07 11:44:36 -06:00
// exceptions/DynamicFields.java
2015-11-14 16:18:05 -08:00
// <20>2016 MindView LLC: see Copyright.txt
2015-06-15 17:47:35 -07:00
// A Class that dynamically adds fields to itself.
// Demonstrates exception chaining.
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 };
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for(Object[] obj : fields) {
result.append(obj[0]);
result.append(": ");
result.append(obj[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;
// Recursive 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);
2015-11-03 12:00:44 -08:00
System.out.println(df);
2015-06-15 17:47:35 -07:00
try {
df.setField("d", "A value for d");
df.setField("number", 47);
df.setField("number2", 48);
2015-11-03 12:00:44 -08:00
System.out.println(df);
2015-06-15 17:47:35 -07:00
df.setField("d", "A new value for d");
df.setField("number3", 11);
2015-11-03 12:00:44 -08:00
System.out.println("df: " + df);
System.out.println("df.getField(\"d\") : "
+ df.getField("d"));
2015-06-15 17:47:35 -07:00
Object field = df.setField("d", null); // Exception
} catch(NoSuchFieldException |
DynamicFieldsException e) {
e.printStackTrace(System.out);
}
}
2015-09-07 11:44:36 -06:00
}
/* Output:
2015-06-15 17:47:35 -07:00
null: null
null: null
null: null
d: A value for d
number: 47
number2: 48
df: d: A new value for d
number: 47
number2: 48
number3: 11
df.getField("d") : A new value for d
DynamicFieldsException
at DynamicFields.setField(DynamicFields.java:64)
at DynamicFields.main(DynamicFields.java:94)
Caused by: java.lang.NullPointerException
at DynamicFields.setField(DynamicFields.java:66)
... 1 more
2015-09-07 11:44:36 -06:00
*/