加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 使用/不使用断言进行编译时的javap差异

发布时间:2020-12-16 10:03:27 所属栏目:安全 来源:网络整理
导读:不耐烦的 Scala第15章练习10:添加断言(n = 0到一个阶乘方法.编译启用断言并验证factorial(-1)是否抛出异常.编译时没有断言.会发生什么?使用javap检查什么发生在断言电话上. 我的代码: object Test { def factorial(x: Int): Int = { assert(x = 0,"Call t
不耐烦的 Scala第15章练习10:添加断言(n> = 0到一个阶乘方法.编译启用断言并验证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中的区别…

解决方法

当我使用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输出,而不是测试$.有关详细信息,请参阅例如Programming in Scala:

For every Scala singleton object,the compiler will create a Java
class for the object with a dollar sign added to the end. For a
singleton object named App,the compiler produces a Java class named
App$. This class has all the methods and fields of the Scala
singleton object.

如果列出已编译的目录的内容,则会看到Test.class和Test $.class.使用javap -v Test $会显示后者,这是你会发现差异的地方.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读