2012-07-08 3 views
4

Скала для нечувствительного Глава 15 Упражнение 10: Добавить assert(n >= 0 в метод factorial. Скомпилируйте с утверждениями и убедитесь, что factorial(-1) выдает исключение. Скомпилируйте без утверждений. Что происходит? Используйте javap, чтобы проверить, что произошло с вызовом подтверждения.Разница в 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 ...

ответ

5

Когда Я стараюсь это с 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), или, более вероятно, что вы смотрите на выходе javap для Test класса , не Test$. Смотрите, например Programming in Scala более подробно:

Для каждого Scala единственного объекта, компилятор создаст Java класса для объекта со знаком доллара добавляется в конце. Для объекта singleton с именем App компилятор создает класс Java с именем App$. Этот класс имеет все методы и поля объекта Singleton Scala .

Если список содержимого каталога, вы скомпилированный, вы увидите, как Test.class и Test$.class. Используя javap -v Test$ покажет вам последнее, в котором вы найдете разницу.