Key Java JML proover передает этот алгоритм, который считывает определенный элемент массива, который вызывает исключение NullPointerException? вместо этого он должен потерпеть неудачу
Я пытаюсь лучше понять пределы проверки ключей для Java. Я придумал сценарий, в котором определенный элемент массива вызовет исключение нулевого указателя. Когда я пропускаю это через прувер, он проходит. Есть идеи, почему это так? Он должен завершиться ошибкой, поскольку нулевой указатель будет брошен на элемент массива 86454. Обратите внимание, что "normal_behaviour" означает, что он должен завершиться без исключений.
/*@
@ normal_behaviour
@ requires true;
@ ensures \result == 7;
@*/
public static int tmp() {
Object[] arr = new Object[999999];
arr[86454] = new Integer(6);
for (int i=0;i<999999;i++){
if (arr[i]!=null && arr[i].equals(new Integer(6))){
throw new NullPointerException();
}
}
return 7;
}
1 ответ
Ваша спецификация охватывает только нормальное поведение, а не исключительный случай.
Нормальное поведение означает, что после выполнения метода должны соблюдаться все постусловия. Следовательно, существует возвращаемое значение, и вам разрешен доступ к нему (\result
). В исключительном случае вашrequires
пункт не будет четко определен.
Если вы хотите указать случай, когда возникает исключение, вы должны использовать exceptional_behavior
и в случае, если вы хотите показать "без исключений", используйте behavior
. Оба в сочетании сsignals
пункт. Например, чтобы показать отсутствие исключений, используйте следующее:
/*@ public behavior
requires true;
signals (Exception e) false;
*/
Этот контракт не может быть выполнен методом, который может вызвать исключение.
См. Главу 7 (особенно "7.3.3 Семантика случаев спецификации нормального поведения") ключевой книги.