而且,只要命令行没有指定与已破坏的形参定义相匹配的实参,程序也可以 执行得很好。这种被蒙蔽的错误很容易导致不完善代码的发布。
假设我想在实际处理实参之前查找字段信息,清单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);
}
Java编程的动态性,第3部分: 应用反射(4)
时间:2011-04-09 IBM Dennis M. Sosnoski
实际的库实现还涉及到本文没有提及的几个类。我不打算一一介绍每一个类,因为其中大 部分类都与库的反射方面不相关。我将提到的是,我选择将目标对象存为 ArgumentProcessor 类的一个字段,并在这个类中实现一个形参字段的真正设置。这种方法 为参数处理提供了一个简单的模式: ArgumentProcessor 类扫描实参以发现形参标记,为每 个标记查找相应的形参定义(总是 ParameterDef 的一个子类),再调用这个定义的 handle() 方法。handle() 方法在解释完实参值之后,又调用 ArgumentProcessor 的 setValue() 方法。清单5显示了 ArgumentProcessor 类的不完整版本,包括在构造函数中的 形参绑定调用以及 setValue() 方法:
清单 5. 主库类的部分清单
public class ArgumentProcessor
{
private Object m_targetObject; // parameter value object
private int m_currentIndex; // current argument position
...
public ArgumentProcessor(ParameterDef[] parms, Object target) {
// bind all parameters to target class
for (int i = 0; i < parms.length; i++) {
parms[i].bindToClass(target.getClass());
}
// save target object for later use
m_targetObject = target;
}
public void setValue(Object value, Field field) {
try {
// set parameter field value using reflection
field.set(m_targetObject, value);
} catch (IllegalAccessException ex) {
throw new IllegalArgumentException("Field " + field.getName() +
" is not accessible in object of class " +
m_targetObject.getClass().getName());
}
}
public void reportArgumentError(char flag, St
|