У меня есть две различные реализации функции (например, размер дерева), которая является рекурсивной и одна использует явный стек.Безопасно ли поймать StackOverflowError в Java?
Рекурсивный очень быстрый (вероятно, потому, что ему не нужно ничего выделять в куче), но может вызвать переполнение стека на некоторых «редких» входах (в примере дерева это было бы на любом неуравновешенном дереве) , Явная версия медленнее, но вряд ли вызовет переполнение стека.
Насколько безопасно использовать рекурсивную реализацию по умолчанию и восстановить из исключения StackOverflowError, выполнив явный вариант?
Это считается плохой практикой?
Вот небольшой пример кода:
interface Node {
List<? extends Node> getSons();
}
static int sizeRec (Node root) {
int result = 1;
for (Node son : root.getSons()) {
result += sizeRec(son);
}
return result;
}
static int sizeStack (Node root) {
Stack<Node> stack = new Stack<Node>();
stack.add(root);
int size = 0;
while (! stack.isEmpty()) {
Node x = stack.pop();
size ++;
for (Node son : x.getSons()) {
stack.push(son);
}
}
return size;
}
static int size (Node root) {
try {
return sizeRec(root);
} catch (StackOverflowError e) {
return sizeStack(root);
}
}
AFAIK нет никаких проблем с ловли StackOverflowError - это просто очень редко, что нужно сделать, и * большую часть времени * это указывает на ошибку, а не структуры данных слишком сложным для обработки рекурсивно , – immibis
Как вы оцениваете быстрее и медленнее в этом случае? Вы сравнили это? Если да, то как? –
@immibis: Я не уверен. Если вы поймаете исключение, то что? Вероятно, ваш стек не находится в состоянии ожидания, и как бы вы восстановились после такой ошибки и убедитесь, что ваша программа стабильна? –