er){
return parser.nextInt();
}
无缝产生
在编译阶段,代码产生为源代码产生带来了额外的负担。你可以使用一个方便的配置编译工具(例如Ant)来处理这个问题。在这里,我要为这篇文章的例子产生代码,我创建了以下的任务:
dir = "."
fork = "yes">
两个参数指定了源代码的目的包,以及用来创建载入过程的类。一旦定义好任务并且将它集成到编译的过程中,代码产生就会成为编译过程的一部分。
Java中利用Reflection API优化代码(5)
时间:2010-12-19
对比工作方案
对于这两个工作方案,我们现在来回顾分析一下。
当你在运行时遇到问题时,这些方案的真正不同之处是显而易见的。在runtime reflection的方案中,由于广泛地使用reflection和递归,你可能得到的是一个难懂的堆栈跟踪。产生代码的方式可让你得到一个简单的堆栈跟踪,这样你就可以回溯到产生的源代码作调试。
以下就是一个例子,由同样的错误产生的两种堆栈跟踪。我将让你判断一下使用哪一种作调试。(要注意的是为了便于阅读,我已经移除了com.thoughtworks.rettig包的限定)
Runtime Reflection Exception:
java.lang.NumberFormatException: itemName
at java.lang.Integer.parseInt(Integer.java:409)
at java.lang.Integer.parseInt(Integer.java:458)
at ...util.SimpleFileIterator.nextInt(SimpleFileIterator.java:82)
at ...dataLoader.SimpleFileLoadManager$1.load(SimpleFileLoadManager.java:44)
at ...dataLoader.ReflectiveObjectLoader.initializeInstance(ReflectiveObjectLoader.java:129)
at ...dataLoader.ReflectiveObjectLoader.constructObject(ReflectiveObjectLoader.java, Compiled Code)
at ...dataLoader.ReflectiveObjectLoader.initializeInstance(ReflectiveObjectLoader.java:134)
at ...dataLoader.ReflectiveObjectLoader.constructObjectArray(ReflectiveObjectLoader.java, Compiled Code)
at ...dataLoader.ReflectiveObjectLoader.initializeArray(ReflectiveObjectLoader.java:39)
at ...dataLoader.ReflectiveObjectLoader.initializeInstance(ReflectiveObjectLoader.java:123)
at ...dataLoader.ReflectiveObjectLoader.constructObject(ReflectiveObjectLoader.java, Compiled Code)
at ...dataLoader.ReflectiveObjectLoader.initializeInstance(ReflectiveObjectLoader.java:134)
at ...dataLoader.ReflectiveObjectLoader.initializeInstance(ReflectiveObjectLoader.java:103)
以下是产生代码的Exception
java.lang.NumberFormatException: itemName
at java.lang.Integer.parseInt(Integer.java:409)
at java.lang.Integer.parseInt(Integer.java:458)
at ...util.SimpleFileIterator.nextInt(SimpleFileIterator.java:82)
at ....example.generated.PurchaseOrderLoader.loadint(PurchaseOrderLoader.java:32)
at ....example.generated.PurchaseOrderLoader.loadLineItem(PurchaseOrderLoader.java:22)
at ....example.generated.PurchaseOrderLoader.loadLineItemArray(PurchaseOrderLoader.java, Compiled Code)
at ....example.generated.PurchaseOrderLoader.loadPurchaseOrder(PurchaseOrderLoader.java:27)
对于runtime reflection,我们要分离出问题的话需要作很多的记录日志。在载入的过程中,大量地使用记录日志明显是不适合的。使用reflection,你可以令堆栈跟踪更加有意义,不过这会令已经复杂的环境更加复杂化。使用产生代码的方法时,得到的代码只是记下runtime reflection将如何处理这些情形。
这两种实现方式在性能方面也有着区别。我惊奇地发现,在使用 |