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

在Java中捕获StackOverflowError是否安全?

发布时间:2020-12-14 05:42:36 所属栏目: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);
  }
}

解决方法

嗯,这是一个意见问题.但是,我不相信你应该这样做.首先,你的逻辑扭曲了异常处理的意义(“例外”的例外而不是逻辑),其他程序员在解释你的代码时会遇到问题.

除此之外,您不应该捕获“Erros”,它表示环境中的运行时问题.你应该问自己是否值得忘记一些好的做法.也许,你可以尝试调整运行时配置以适应应用程序或者放置额外的验证逻辑……你的呼叫在那里……但是考虑到安全性,你实际上不能说你很好,因为我们不知道堆栈状态如何现在,不同的JRE实现可能会有所不同..

最后,对于底部的问题:这是一种不好的做法,并不安全.

来自https://softwareengineering.stackexchange.com/questions/209099/is-it-ever-okay-to-catch-stackoverflowerror-in-java的报价:

surely there are situations where a stack overflow might leave an application inconsistent just like a memory exhaustion. Just imagine that some object is constructed and then initialized with the help of nested internal method calls – if one of them throws,the object may very well be in a state not supposed to be possible,just as if an allocation had failed. But that doesn’t mean that your solution couldn’t still be the best one

它有一个被称为错误而不是异常的理由……

来自docs:

public abstract class VirtualMachineError
extends Error:
Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating

public class Error extends Throwable: An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error,though a “normal” condition,is also a subclass of Error because most applications should not try to catch it. A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught,since these errors are abnormal conditions that should never occur. That is,Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.

(编辑:李大同)

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

    推荐文章
      热点阅读