对于急躁的第15章练习10:将assert(n >= 0添加到factorial方法。在启用断言的情况下编译,并验证factorial(-1)抛出异常。编译时没有断言。会发生什么?使用javap检查断言调用发生了什么。
我的代码:
object Test {
def factorial(x: Int): Int = {
assert(x >= 0, "Call to factorial must be >= 0!")
x match {
case 0 => 1
case x: Int => x * factorial(x - 1)
}
}
def main(args: Array[String]): Unit = {
factorial(-1)
}
}我首先用scalac编译,然后使用javap Test检查它,然后再用scalac -Xelide-below MAXIMUM编译,然后用相同的命令进行检查--我似乎找不到两者之间的区别。
我知道使用断言编译会在我试图执行程序时抛出异常,而没有断言的编译会导致堆栈溢出错误,但是我找不到javap中的不同之处。
发布于 2012-07-08 14:23:52
当我在javap -v中尝试这一点时,我发现在版本中启用了断言,但在另一行中却没有:
20: invokevirtual #27; //Method scala/Predef$.assert:(ZLscala/Function0;)V
...
27: if_icmpne 34
30: iconst_1
31: goto 55所以这看起来当然没问题。
问题可能是,您没有查看字节码(这需要-c或-v标志来实现javap),或者--更有可能的是--您查看的是Test类的javap输出,而不是Test$。有关更多细节,请参见http://www.artima.com/pins1ed/combining-scala-and-java.html:
对于每个singleton对象,编译器将为对象创建一个Java类,并在末尾添加一个美元符号。对于名为
App的单例对象,编译器生成名为App$的Java类。这个类拥有singleton对象的所有方法和字段。
如果列出已编译的目录的内容,您将看到Test.class和Test$.class。使用javap -v Test$将向您展示后者,这就是您发现差异的地方。
https://stackoverflow.com/questions/11381122
复制相似问题