繁体   English   中英

成品中的printStackTrace()。 什么时候,为什么?

[英]printStackTrace() in a finished product. When and why?

从许多资料中得出的结论是,使用printStackTrace进行错误处理是不好的做法。 这是一个

现在,我感到很奇怪:在什么情况下打印stacktrace是有效的解决方案? 出于争论的目的,让我们假设我们不是在诸如微波炉或香蕉之类的系统上工作,而是在基本的现成PC上工作。

我问这个问题的原因本身可以看作一个问题,但是我会告诉你的:

我正在开发一种可以与AI一起玩的类似蛇的游戏,并专门用于此目的。 所有这些AI都应扩展一个名为SnakeLogic的抽象类。 所有这些AI都还应该驻留在特定文件夹中的独立.jar存档中,主程序可以在其中找到它们并使用类加载器列出它们。

然后,如果所有星星都排成一行,则用户可以从列表中选择自己的AI之一,并使用该AI进行游戏。

现在,我的主程序中有一个方法可以像这样从AI获取下一步操作:

public void startGame(int speed) {        
    gameInterface.showWindow();
    Runnable moveCmd = () -> {
        try {

            for (Player player : snakeGame.getPlayers()) {
                if (player.isDead()) {
                    continue;
                }

                String move = player.getLogicHandler().getMove();

                Direction direction = Direction.directionFromString(move);
                snakeGame.makeMove(player, direction);
            }

            gameInterface.getFrame().repaint();
            snakeGame.wait(speed);

            if (snakeGame.gameOver()) {
                stopGame();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            stopGame();
        }
    };

    /* moveSchedule is an instance of ScheduledExecutorService */
    moveSchedule.scheduleAtFixedRate(moveCmd, 1000, speed, TimeUnit.MILLISECONDS);        
}

我不会太参与上面的代码。 但是,我想提请您注意try-catch语句。 如您所见,如果在执行moveCmd runnable期间某处发生异常,我将打印moveCmd并结束游戏。 这是我好奇的根源:如果我不这样打印stacktrace,或者如果我完全删除了try-catch,则在执行该块的过程中发生运行时异常的情况下,我永远不会出错。 为什么? 是因为它包裹在可运行对象内部吗? 另请注意,该行snakeGame.makeMove(player, direction); 在主程序中不调用任何代码; snakeGame是一个实例SnakeLogic ,后者位于一个外部.jar。

如果删除try-catch,为什么没有出现任何错误? 另外,在这种情况下,打印stacktrace是一个好主意吗?

我了解这为您带来了两个问题:主题和以上。 我想强调这个话题,所以不要对第二个问题过于关注。 尽管洞察力已得到适当记录,但我的代码中没有任何损坏。

处理错误和异常时,您需要稍微改变一下思维过程。 打印错误跟踪始终是一个好习惯。 现在的问题是在哪里打印。 默认情况下, printStackTrace打印到标准控制台。 当然,您可以像Tomcat一样将输出重定向到日志文件,但是如果您询问我,这可以解决。

在生产和预生产系统中,甚至在可分发的spftware中,您在其中将桌面应用程序分发给用户以在PC上运行,您可能会也可能没有控制台的专用访问权限。 关闭控制台或应用完成后,控制台上的打印内容也会丢失。 您需要将错误保留在某处,以便以后进行分析。 通常,人们将应用程序设计为压缩并定期将错误日志发送给开发人员进行分析。

现在,如果您考虑整个场景,最重要的是将错误保留在某处,以便以后进行分析。 因此,通常在循环日志文件或数据库中进行操作。 控制台不足。 因此,顺便说一句,catch块应该有一个log语句来记录异常。

Exception.printStackTrace()的问题在于它(最有可能)写入到控制台,这是一个同步操作。 更不用说在大多数平台上,写入控制台的速度很慢。 您不希望延迟执行线程,直到写入完整的堆栈跟踪。 因此最好将其移交给log4j之类的日志框架,该框架具有将完整的堆栈跟踪异步写入文件的功能(可以使用其他附加程序),这样执行线程可以立即返回给被调用方,但日志中仍包含必需的内容。细节。

因此,这是同步写入还是异步写入的问题。 正如Nazgul所指出的,您必须将异常记录在系统中,以便以后进行适用的分析。

注意:异步日志记录的一个问题是,如果进程突然终止,如kill -9或系统断电,则可以在OS有机会将缓冲的内容写入磁盘之前松开缓冲的内容

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM