简体   繁体   English

正确地抛出和捕获异常

[英]Throwing and catching exceptions correctly

So I have this one question. 所以我有这个问题。 Lets say we have classes: Main , Info , Cats , Food 让我们说我们有课程: MainInfoCatsFood

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.

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