jshell продолжает выполнять мой скрипт после того, как возникнет исключение. Как сделать так, чтобы это прекратилось?

Я попытался написать несколько сценариев jshell. Когда возникает исключение, jshell продолжает выполнять следующую строку.

Как сделать так, чтобы мои скрипты вели себя как обычные Java-программы?

Изменить: я просто запускаю его как jshell SCR.jsh.

Использование throw new Exception() или 1/0 не препятствует выполнению следующей строки.

Сценарий включает в себя такой оператор:

System.out.println(1/0)
System.out.println("foo")
/exit

Я думал, что вторая строка недоступна. Это то, что я ожидал. Но после того, как исключение напечатано, также печатается foo.


person cshu    schedule 22.09.2017    source источник
comment
Этот вопрос выиграет от примера, демонстрирующего рассматриваемое поведение.   -  person David Conrad    schedule 22.09.2017
comment
Было бы неплохо взглянуть на MCVE для решения этой проблемы.   -  person Naman    schedule 22.09.2017
comment
Вопросы, требующие помощи в отладке (почему этот код не работает?), должны включать желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для их воспроизведения, в самом вопросе. Вопросы без четкой формулировки проблемы бесполезны для других читателей. См. Как создать минимально воспроизводимый пример. Используйте ссылку редактирования, чтобы улучшить свой вопрос — не добавляйте дополнительную информацию через комментарии. Спасибо!   -  person GhostCat    schedule 22.09.2017


Ответы (2)


Насколько я понимаю, причина, по которой jshell выполняет все строки в вашем скрипте даже после того, как одна из них выдает исключение, заключается в том, что он обрабатывает ваш скрипт как список Snippet.

Все выражения принимаются как сниппеты. Сюда входят выражения без побочных эффектов, такие как константы, доступ к переменным и лямбда-выражения:

1
a
x -> x+1
(String s) -> s.length()

а также выражения с побочными эффектами, такие как присваивания и вызовы методов

System.out.println("Hello world");
new BufferedReader(new InputStreamReader(System.in))

Таким образом, даже один из фрагментов генерирует исключение, остальные должны следовать Read-Eval- Шаблон Print Loop(REPL). Как и ответил себе, преобразование кода в виде блока операторов помечает его как один Snippet, который при выдаче java.lang.ArithmeticException отмечает его завершение тем самым.

Хотя в идеале такие операторы следует определять как фрагмент объявления.

Фрагмент объявления (ClassDeclaration, InterfaceDeclaration, MethodDeclaration или FieldDeclaration) — это фрагмент, который явно вводит имя, на которое могут ссылаться другие фрагменты.

person Naman    schedule 22.09.2017

Наконец, я думаю, что нашел обходной путь:

{
    System.out.println(1/0);
    System.out.println("foo");
}
/exit

Теперь это намного ближе к знакомому коду Java.

Не только исключение работает так, как ожидалось, но и точки с запятой также становятся необходимыми внутри блока.

person cshu    schedule 22.09.2017