[英]Throwing and catching exceptions correctly
So I have this one question. 所以我有这个问题。 Lets say we have classes:
Main
, Info
, Cats
, Food
让我们说我们有课程:
Main
, Info
, Cats
, Food
Now, lets say that in main we create new object Info
. 现在,让我们说在main中我们创建新的对象
Info
。 In Info
object we are saving list of Cats
that have been created. 在
Info
对象中,我们保存已创建的Cats
列表。 Cats
are being created and stored in Info
class and Food
is being created and stored in Cats
class. 正在创建
Cats
并将其存储在Info
类中,并且正在创建Food
并将其存储在Cats
类中。 Now lets say, that in Main
class, I want to get specific Food
object, which is stored in Cats
class. 现在让我们说,在
Main
类中,我想获得特定的Food
对象,它存储在Cats
类中。 So, in order to do so we do the following: 因此,为此,我们执行以下操作:
Info.getFood(name)
. Info.getFood(name)
。 Then in Info's
getFood
method we say Cats.getFood(name)
. 然后在
Info's
getFood
方法中我们说Cats.getFood(name)
。 Finally, in Cats
class we have method getFood
, in which we try to find Food object by its field "name". 最后,在
Cats
类中我们有方法getFood
,我们尝试通过其字段“name”查找Food对象。 If we are unable to find such an element, we throw NoSuchElement
exception rather than return an object. 如果我们无法找到这样的元素,我们抛出
NoSuchElement
异常而不是返回一个对象。 Here is my question: 这是我的问题:
If we throw exception in Cats
class getFood
method, should we catch that exception in Main
class (where our interface is), in Info
class (which is our system class) or in both of them? 如果我们在
Cats
类的getFood
方法中抛出异常,我们应该在Main
类(我们的接口所在的位置), Info
类(这是我们的系统类)还是两者中捕获该异常?
Generally speaking, inside a method, if you can do something with the Exception
being thrown (log an error, show an error message, make a different decision in your code, etc), then you should catch it. 一般来说,一个方法里面,如果你可以做的事情
Exception
被抛出(记录错误,显示错误信息,使你的代码不同的决定,等等),那么你就应该抓住它。 Otherwise, just throw it to the calling method. 否则,只需将其抛给调用方法即可。
As with many other coding practices, it all boils down to what you and your team agree on. 与许多其他编码实践一样,这一切都归结为您和您的团队的共识。
A concrete example which isn't related to your code, but which will show you how the decision process can be made. 一个与您的代码无关的具体示例,它将向您展示如何制定决策流程。 Assume the following code:
假设以下代码:
public MyConfiguration loadConfiguration () throws ConfigurationException {
MyConfiguration config = null;
try {
readConfigurationFromFile ();
// Parse configuration string
} catch (IOException ioex) {
throw new ConfigurationException (ioex);
}
return config;
}
private String readConfigurationFromFile () throws IOException {
String configuration = "";
// Read a file on disk, append data to the string.
return configuration;
}
In readConfigurationFromFile ()
, if an exception occurs while reading the file, you'll get an IOException
. 在
readConfigurationFromFile ()
,如果在读取文件时发生异常,则会出现IOException
。 At this point in the code, there's no real action you can take, since this method only reads the configuration file, appends the data to a String
, then returns it. 在代码中的这一点上,您无法采取任何实际操作,因为此方法仅读取配置文件,将数据附加到
String
,然后返回它。
In loadConfiguration ()
, you can surround the call to readConfigurationFromFile ()
with a try/catch
, and throw a more generic exception ( ConfigurationException
). 在
loadConfiguration ()
,您可以使用try/catch
包围对readConfigurationFromFile ()
的调用,并抛出更通用的异常( ConfigurationException
)。 Again, at this point, there's nothing you can do with the exception, except wrap it in a new exception which adds more context information to the original exception that was thrown. 同样,在这一点上,除了将它包装在一个新的异常中,除了将更多的上下文信息添加到抛出的原始异常之外,您无法对异常做任何事情。
Now assume that there's two flavors of your software: a GUI version, and a command-line version. 现在假设您的软件有两种版本:GUI版本和命令行版本。 If you are running the GUI flavor, then the method calling
loadConfiguration
could decide to show an error message to the user whenever a ConfigurationException
is being thrown, so that the user knows that something happened. 如果您正在运行GUI flavor,那么调用
loadConfiguration
的方法可能会在抛出ConfigurationException
时决定向用户显示错误消息,以便用户知道发生了什么。 If you are running the command-line version, then maybe it would be more logical to add an entry to some error log with the exception that was caught. 如果您正在运行命令行版本,那么将某个条目添加到某个错误日志中可能更合乎逻辑,但会捕获该异常。
The following site says "Most of the developers are embarrassed when they have to choose between the two options. This type of decision should not be taken at development time. If you are a development team, it should be discussed between all the developers in order to have a common exception handling policy." 以下网站说:“当他们必须在两个选项之间做出选择时,大多数开发人员都会感到尴尬。这种决定不应该在开发时进行。如果你是一个开发团队,应该在所有开发人员之间按顺序讨论有一个共同的异常处理政策。“
http://en.wikibooks.org/wiki/Java_Programming/Throwing_and_Catching_Exceptions http://en.wikibooks.org/wiki/Java_Programming/Throwing_and_Catching_Exceptions
It depends a lot on what you want to do after throwing that exception. 抛出异常后,这很大程度上取决于你想要做什么。
Say for instance that if all you want is to return any food object from any cat (and as you said 'Info' stores lots of cats) then you might have a catch in Info where you catch the NoSuchElement exception and then create some logic that moves onto the next Cat in Info to get its food! 比如说,如果您想要的只是从任何猫返回任何食物对象(并且正如您所说'信息'存储了许多猫)那么您可能在Info中捕获NoSuchElement异常,然后创建一些逻辑移动到Info中的下一个Cat来获取它的食物! Finally if you exhaust all the 'Cats' in Info with no food found, you can throw another exception inside Info that you catch in Main that lets main know, "There's no food".
最后,如果您在Info中没有找到任何食物的情况下耗尽所有'Cats',您可以在Info中捕获另一个例外,您可以在Main中找到主要知道“没有食物”。
Again that's just an example. 再一次,这只是一个例子。 As people have said, it's not a "Always do this..." kind of answer.
正如人们所说,这不是一个“总是这样......”的答案。 It depends greatly on what you need to do when handling that exception
这在很大程度上取决于处理该异常时您需要做什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.