Java 编程的动态性,第3部分: 应用反射
2010-03-18 00:00:00 来源:WEB开发网最后,清单6显示了 int 形参值的形参定义子类的部分实现。这包括对基类的 bindToClass() 方法(来自 清单4)的重载,这个重载的方法首先调用基类的实现,然后检查找到的字段是否匹配预期的类型。其他特定形参类型( boolean、float、String ,等等)的子类与此十分相似。
清单 6. int 形参定义类
public class IntDef extends ParameterDef
{
private int m_min; // minimum allowed value
private int m_max; // maximum allowed value
public IntDef(char chr, String name, int min, int max) {
super(chr, name);
m_min = min;
m_max = max;
}
protected void bindToClass(Class clas) {
super.bindToClass(clas);
Class type = m_field.getType();
if (type != Integer.class && type != Integer.TYPE) {
throw new IllegalArgumentException("Field '" + m_name +
"'in " + clas.getName() + " is not of type int");
}
}
public void handle(ArgumentProcessor proc) {
// set up for validating
boolean minus = false;
boolean digits = false;
int value = 0;
// convert number supplied in argument list to 'value'
...
// make sure we have a valid value
value = minus ? -value : value;
if (!digits) {
proc.reportArgumentError(m_char, "Missing value");
} else if (value < m_min || value > m_max) {
proc.reportArgumentError(m_char, "Value out of range");
} else {
proc.setValue(new Integer(value), m_field);
}
}
}
结束库
在本文中,我讲述了一个用于处理命令行参数的库的设计过程,作为反射的一个实际的例子。这个库很好地阐明了如何有效地使用反射――它简化应用程序的代码,而且不用明显地牺牲性能。牺牲了多少性能呢?从对我的开发系统的一些快速测试中可以看出,一个简单的测试程序在使用整个库进行了参数处理时比起不带任何参数处理时运行起来平均只慢40毫秒。多出来的这些时间大部分是花在库类和库代码所使用的其他类的装载上,因此,即使是对于那些定义了许多命令行形参和许多实参值的应用程序,也不大可能会比这一结果糟很多。对于我的命令行应用程序,额外的40毫秒根本不能引起我的注意。
它包括我在本文没有提到的一些特性,包括这样一些细节,比如钩子,用于容易地生成一列格式化的形参标记,还有一些描述,有助于为应用程序提供使用指令。欢迎您在自己的程序中使用这个库,并以任何您发现有用的方式扩展这个库。
现在我已讲过了 第1部分中Java类的基础,也讲过了 第2部分中的 Java Reflection API 的原理以及第3部分,本系列剩下的部分将改变话题,讲讲大家不大熟悉的字节码处理。在第4部分,我将从容易的开始,先看看用于使用二进制类的用户友好的 Javassist 库。您是否想转换方法,但是又不愿在字节码中启动程序呢?Javassist 正好适合您的需求。下个月我们将看看如何实现这一点。
更多精彩
赞助商链接