简体   繁体   English

Java错误处理 - 将异常抛给集中式错误处理程序更好吗?

[英]Java Error handling - is it better to throw Exceptions to centralized error handlers?

I've got a decently complex little game going on in Java (solitaire, essentially like the Windows version), but I have yet to do very much error handling. 我有一个相当复杂的小游戏在Java(纸牌,基本上像Windows版本),但我还没有做很多错误处理。

Almost all of the methods across my classes will end up either getting called by an initial constructor (eventually main()), a paintComponent() method, or a mouse event. 我的类中的几乎所有方法都将最终被初始构造函数(最终为main()),paintComponent()方法或鼠标事件调用。 So, my question is, is it bad practice to just use "throws Exception" on all of my lower-level methods, and only do a try/catch at my top-level methods to catch ALL the errors at once? 所以,我的问题是,在我的所有低级方法上使用“throws Exception”是不好的做法,并且只在我的顶级方法中执行try / catch以立即捕获所有错误? (eg 3 try/catches - one for the painting, one for mouse events, one for the main method). (例如3次尝试/捕获 - 一次用于绘画,一次用于鼠标事件,一次用于主要方法)。

I realize this prevents me from easily dealing with errors on-the-spot, but I don't really plan on doing that anyways. 我意识到这使我无法轻易地在现场处理错误,但我并不打算这样做。 My error handling is going to consist of writing to a log, telling the user, and killing the program. 我的错误处理将包括写入日志,告诉用户和终止程序。 Keeping this in mind, is there anything bad with doing my error handling this way? 牢记这一点,以这种方式处理我的错误有什么不好吗?

It depends on how you want to approach the situation. 这取决于你想要如何处理这种情况。
If you just want to catch any possible exception and you don't mind about the handler code, you could simply use "throws exception", and there's nothing BAD with it either. 如果你只是想捕获任何可能的异常并且你不介意处理程序代码,你可以简单地使用“抛出异常”,并且它也没有任何坏处。 It's like a try-catch block that covers all the function. 它就像一个覆盖所有功能的try-catch块。
If you want to write specific code for specific exceptions, you should use try-catch blocks to write appropriate code for each handler. 如果要为特定异常编写特定代码,则应使用try-catch块为每个处理程序编写适当的代码。
Based on what you're saying, any caught exception would just notify the user and exit the application. 根据您的说法,任何捕获的异常都会通知用户并退出应用程序。 Well, in this case you could just use the first approach. 那么,在这种情况下,你可以使用第一种方法。 It's not necessarily the BEST approach, and neither is killing the application, however, if that's your strategy you could just use "throws" for each function. 它不一定是最好的方法,也不是杀死应用程序,但是,如果这是你的策略,你可以只为每个功能使用“抛出”。
Hope that helps! 希望有所帮助!

If that's all you wan't to do in a case of an error, then it makes perfect sense to do it that way. 如果这是你在错误的情况下不想做的事情,那么这样做是完全合理的。 This eliminates code duplication and scattering of related code. 这消除了代码重复和相关代码的散布。 However, if you're thinking of changing how things work in the future (if there's a possibility of this happening), I would suggest to try and push the catch down as far as possible (maybe even eliminating the need for exceptions at all and just logging and exiting right away). 但是,如果您正在考虑改变未来的工作方式(如果有可能发生这种情况),我建议尝试尽可能地推动问题(甚至可能根本不需要例外情况)只是记录并立即退出)。

If you use the exception's inner fields (specifically message , which you can set in construction time), you can even eliminate the need for 3 different catch blocks and just use one (depending on your actual actions in case of an error, of course). 如果您使用异常的内部字段(特别是message ,您可以在构造时间中设置),您甚至可以消除对3个不同的catch块的需要,并且只使用一个(当然,根据您的实际操作,如果出现错误) 。

I wouldn't - the big reason being that it breaks encapsulation. 我不会 - 最重要的原因是它破坏了封装。 The reason why this is important in this case is that your error handling code has one of two futures: 之所以这样是很重要的在这种情况下,你的错误处理代码有两个期货之一:

  1. Becoming enormous to handle in an informative way every error the program can throw. 以信息方式处理程序可能抛出的每个错误都会变得非常庞大。
  2. Be tiny but not helpful at all: "Some error occurred somewhere". 虽然很小但根本没有帮助:“某些地方发生了一些错误”。

To my mind, the best structure is to catch the error, log it, alert the user, and exit as far down as possible . 在我看来,最好的结构是捕获错误,记录错误,提醒用户,并尽可能远地退出。 There's nothing that says your mouse handling code can't exit, right? 没有任何迹象表明您的鼠标处理代码无法退出,对吧?

In fact, I would create an error handler class that you can call from just about anywhere, and it handles the notification and logging. 实际上,我会创建一个可以从任何地方调用的错误处理程序类,它会处理通知和日志记录。 Then your exception handlers can just populate it with the message to display/log, and all other code is shared. 然后,您的异常处理程序可以使用要显示/记录的消息填充它,并共享所有其他代码。 It will cost you less typing to delegate to this class than adding throws Exception at the end of every function everywhere. 委托给这个类的代码比在每个函数的末尾添加throws Exception会花费更少

If you must have a top level handler, it should just catch any unexpected runtime errors, so that you can log it and show the user that the program is really quitting for an error, and not just dump to the desktop. 如果你必须有一个顶级处理程序,它应该只捕获任何意外的运行时错误,这样你就可以记录它并向用户显示该程序实际上已经退出错误,而不仅仅是转储到桌面。 All other errors - even if you just want to bail out - should be caught as close to "where the exception has meaning" as possible. 所有其他错误 - 即使你只是想要拯救 - 应尽可能接近“异常有意义的地方”。

I do the same thing as you are describing most of the time. 我做的和你大部分时间描述的一样。 What you're basically doing is working around the stupid checked exceptions that Java has. 你基本上做的是解决Java所具有的愚蠢的已检查异常。 It shouldn't even be necessary to add 'throws Exception' everywhere. 甚至不需要在任何地方添加“抛出异常”。

If I'm working on an API that other users will use I may create specific exceptions to show what is going on in case they want to handle different exceptions in different ways. 如果我正在处理其他用户将使用的API,我可能会创建特定的异常来显示正在发生的事情,以防他们想要以不同的方式处理不同的异常。

If an error is severe enough to always exit the program, you may be better of throwing a RuntimeException instead. 如果错误严重到总是退出程序,那么最好抛出RuntimeException。 They are used to indicate unrecoverable errors and will avoid problems with putting "throws Exception" everywhere. 它们用于指示不可恢复的错误,并避免在任何地方放置“抛出异常”的问题。 You should have a handler for RuntimeExceptions anyway to provide a user-friendly error report in case they happen. 无论如何,您应该拥有RuntimeExceptions的处理程序,以便在发生时提供用户友好的错误报告。

If you throw checked exceptions, they should be as specific as possible. 如果抛出已检查的异常,它们应尽可能具体。 Throwing and catching Exception can hide other exceptions that are thrown (including RuntimeExceptions) that you didn't intend and could have been handled differently. 抛出和捕获异常可以隐藏您不想要并且可能以不同方式处理的其他抛出的异常(包括RuntimeExceptions)。 If you want to throw a general exception, you can always create your own exception class and throw that instead. 如果要抛出一般异常,可以始终创建自己的异常类并将其抛出。

The exception handling can depend on the context so there's not one way to handle everything. 异常处理可能取决于上下文,因此没有一种方法可以处理所有事情。 If the user clicks a button to open a file and there's an error reading it, then it would be ok to throw an IOException up to the UI layer and display an error message there. 如果用户单击按钮打开文件并且读取它时出错,则可以将IOException抛出到UI层并在那里显示错误消息。 On the other hand, an IOException while creating a temporary file could be handled lower down by retrying in another directory. 另一方面,创建临时文件时的IOException可以通过在另一个目录中重试来降低。

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

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