Java 编程的动态性,第3部分: 应用反射
2010-03-18 00:00:00 来源:WEB开发网最后剩下的部分就是处理错误报告(例如一个未知的形参标记字符或者一个超出范围的数字值)。出于这个目的,我将定义 ArgumentErrorException 作为一个未经检查的异常,如果出现了某个这一类的错误,就将抛出这个异常。如果这个异常没有被捕捉到,它将立即关闭应用程序,并将一条错误消息和栈跟踪输出到控制台。一个替代的方法是,您也可以在代码中直接捕捉这个异常,并且用其他方式处理异常(例如,可能会与使用信息一起输出真正的错误消息)。
实现库
为了让这个库像计划的那样使用反射,它需要查找由形参定义数组指定的一些字段,然后将适当的值存到这些来自相应的命令行参数的字段中。这项任务可以通过只查找实际的命令行参数所需的字段信息来处理,但是我反而选择将查找和使用分开。我将预先找到所有的字段,然后只使用在参数处理期间已经被找到的信息。
预先找到所有的字段是一种防错性编程的步骤,这样做可以消除使用反射时带来的一个潜在的问题。如果我只是查找需要的字段,那么就很容易破坏一个形参定义(例如,输错相应的字段名),而且还不能认识到有错误发生。这里不会有编译时错误,因为字段名是作为 String 传递的,而且,只要命令行没有指定与已破坏的形参定义相匹配的实参,程序也可以执行得很好。这种被蒙蔽的错误很容易导致不完善代码的发布。
假设我想在实际处理实参之前查找字段信息,清单4显示了用于形参定义的基类的实现,这个实现带有一个 bindToClass() 方法,用于处理字段查找。
清单 4. 用于形参定义的基类
public abstract class ParameterDef
{
protected char m_char; // argument flag character
protected String m_name; // parameter field name
protected Field m_field; // actual parameter field
protected ParameterDef(char chr, String name) {
m_char = chr;
m_name = name;
}
public char getFlag() {
return m_char;
}
protected void bindToClass(Class clas) {
try {
// handle the field look up and accessibility
m_field = clas.getDeclaredField(m_name);
m_field.setAccessible(true);
} catch (NoSuchFieldException ex) {
throw new IllegalArgumentException("Field '" +
m_name + "' not found in " + clas.getName());
}
}
public abstract void handle(ArgumentProcessor proc);
}
更多精彩
赞助商链接