在java中对每个方法使用一个大的try-catch是一个已知的好习惯吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18784549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:02:32  来源:igfitidea点击:

Is it a known good practice to use a big try-catch per method in java?

javaexception-handlingtry-catch

提问by Adrián Pérez

I've been interviewed recently and the interviewer wanted me to do a technical test to see my knowledge. After I finished it he gave me feedback about how I did it, which I didn't expect and I appreciated, since few interviewers do it if they don't want to hire you.

最近面试了,面试官要我做个技术测试,看看我的知识。在我完成之后,他给了我关于我是如何做到的反馈,这是我没想到的,我很感激,因为如果他们不想雇用你,很少有面试官会这样做。

One of the things he told me that he saw bad about my code was that I used more than one try-catch block inside each method I wrote. This calls my attention since I see it interesting.

他告诉我他认为我的代码不好的一件事是我在我编写的每个方法中使用了多个 try-catch 块。这引起了我的注意,因为我觉得它很有趣。

I believe at the moment that I should make try-catch blocks where there is a semantically distinguishable block of code which has one or more methods that can throw exceptions needed to be caught. The only exception to this that I followed was that if two methods throw the same exception type, I better put them in different try-catch blocks to clearly distinguish when debugging where and why an exception was thrown.

我现在相信我应该在有语义可区分的代码块的地方制作 try-catch 块,该块具有一个或多个可以抛出需要捕获的异常的方法。我遵循的唯一例外是,如果两个方法抛出相同的异常类型,我最好将它们放在不同的 try-catch 块中,以便在调试时清楚地区分抛出异常的位置和原因。

This strongly differs from what the interviewer wanted me to do. So is using just one try-catch block per method a known good practice? If it is a known good practice what are the benefits of doing it?

这与面试官希望我做的完全不同。那么每个方法只使用一个 try-catch 块是一种已知的好做法吗?如果这是一种已知的良好做法,这样做有什么好处?

EDIT: I greatly appreciate your thoughts on this, this is very good. Although take note that I'm asking if it is a known good practice. This is, if most programmers would agree on this, and or this is written as a good practice in some book

编辑:我非常感谢您对此的想法,这非常好。尽管请注意,我在问这是否是一种已知的良好做法。这是,如果大多数程序员都同意这一点,或者这在某本书中被写成一个很好的做法

采纳答案by Bartosz Bilicki

For me, two try-catch blocks makes most methods too long. It obfuscates the intention if the method is doing many things.

对我来说,两个 try-catch 块使大多数方法太长。如果该方法正在做很多事情,它会混淆意图。

With two try-catch blocks, it's doing at least four things, to be precise

有两个 try-catch 块,它至少做了四件事,准确地说

  • two cases for main flow (two try blocks)
  • two cases for error handling (catch blocks)
  • 主流的两种情况(两个 try 块)
  • 错误处理的两种情况(catch 块)

I would rather make short and clear methods out of each try-catch block- like

我宁愿从每个 try-catch 块中制作简短而清晰的方法 - 就像

private getHostNameFromConfigFile(String configFile, String defaultHostName) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(configFile));
        return reader.readLine();
    } catch (IOException e) {
        return defaultHostName;
    }
}
public Collection<String> readServerHostnames(File mainServerConfigFile, File  backupServerConfigFile) {
    String mainServerHostname=getHostNameFromConfigFile(mainServerConfigFile,"default- server.example.org");
    String backupServerHostName=getHostNameFromConfigFile(backupServerConfigFile,"default- server.example.ru")
    return Arrays.asList(mainServerHostname,backupServerHostName );
}

Robert C. Martin in 'Clean Code' takes it to next level, suggesting:

'Clean Code' 中的 Robert C. Martin 将其提升到了一个新的水平,他建议:

if the keyword 'try' exists in a function, it should be the very first word in the function and that there should be nothing after the catch/finally blocks.

如果函数中存在关键字“try”,则它应该是函数中的第一个单词,并且在 catch/finally 块之后应该没有任何内容。

I would definitely refactor the method with two separate try/catch blocks into smaller methods.

我肯定会用两个单独的 try/catch 块将方法重构为更小的方法。

回答by Eel Lee

This is another thing that often starts Java-flamewar... ;-)

这是另一个经常启动 Java-flamewar 的事情...... ;-)

Basically, for the performance matters only throwing exceptions. So using few try-catchblocks shouldn't affect a performance at all. In some opinion writing code that way obfuscates the code and does not even recall "clean code", in others opinion it's better to use tryonly for lines which can actually throw any exception.

基本上,对于性能而言,只抛出异常。所以使用几个try-catch块根本不应该影响性能。在某些人看来,以这种方式编写代码会混淆代码,甚至不记得“干净的代码”,而在其他人看来,最好try仅用于实际上可以抛出任何异常的行。

It's up to you decide (or the team convention).

这取决于您(或团队约定)。

回答by OldCurmudgeon

I'd say that if you find yourself wrapping two separate blocks of code with try/catchyou should consider refactoring those blocks into separate methods. If this is a pattern you used in your interview than perhaps you misunderstood your interviewer.

我想说的是,如果您发现自己包装了两个单独的代码块,try/catch您应该考虑将这些块重构为单独的方法。如果这是您在面试中使用的模式,那么您可能误解了面试官。

It is perfectly fine to use two try/catchblocks if the algorithm requires it. I have often used a new try/catchin a catch block to ensure a safe cleanup so a blanket statement is not possible.

try/catch如果算法需要,最好使用两个块。我经常try/catch在 catch 块中使用 new来确保安全清理,因此不可能有全面的声明。

回答by dharam

To answer your question, when we talk about modern day JVMs which are actually applying a lot of optimizations in the code, when you write some code which is inefficient then the JVM will automatically introduce optimizations.

为了回答您的问题,当我们谈论实际上在代码中应用大量优化的现代 JVM 时,当您编写一些效率低下的代码时,JVM 会自动引入优化。

Please refer the answer in (Java: overhead of entering/using "try-catch" blocks?).

请参考(Java:进入/使用“try-catch”块的开销?)中的答案。

So the good practice thing is not of much importance.

所以好的做法并不重要。

On a personal note, I believe that one must not encapsulate anything in a try-catch, static, synchronizedetc blocks un-necessarily.

就我个人而言,我认为,一个在一定不要封装什么try-catchstaticsynchronized等块未必然。

Let us make our code more readable to the ones who will be working on this. If an exception is caught, it is better to explicitly make it prominent that which piece of code is throwing it.

让我们使我们的代码对将要从事此工作的人更具可读性。如果捕获到异常,最好明确指出是哪一段代码抛出它。

No guessing for the reader, that is why JVMs are smart, write as you want , make it better for humans and JVM takes care of the optimization part.

读者无需猜测,这就是为什么 JVM 很聪明,可以随心所欲地编写,使其对人类更好,而 JVM 负责优化部分。

EDIT:I have read plenty of books and I didn't find it any place which says that one big try catch is better than multiple small ones.

编辑:我读过很多书,但我没有发现任何地方说一次大的尝试比多个小的好。

Moreover, many in the developer community believe the opposite.

此外,开发人员社区中的许多人认为相反。

回答by ssantos

As for me, it's clearer to have just one try-catchblock wrapping all the 'hazardous' code in a method. Regarding who to blame when two lines throw the same exception, you'll always have the stacktrace.

对于我来说,只用一个try-catch块将所有“危险”代码包装在一个方法中会更清晰。关于当两行抛出相同异常时该怪谁,您将始终拥有堆栈跟踪。

Besides, having more than one try-catchinside a method usually means having more than one returnlines (which can also make hard to follow code execution at a sight), as chances are that if something goes wrong in the first try-catch, it won't make sense to keep running the rest of the code.

此外,try-catch在一个方法中有不止一个通常意味着有不止return一行(这也使得一看就很难跟踪代码执行),因为很可能如果第一个出现问题try-catch,就没有意义了继续运行其余的代码。

Here you can find some 'standard' best practices, just in case you may find them useful.-

在这里您可以找到一些“标准”最佳实践,以防万一您发现它们有用。-

http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/

http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/

回答by Chris

It's also important to consider the context of the code. If you're writing code with heavy IO then you may need to know which parts of the code are failing. I didn't see anywhere yet a point that try...catch is meant to give you a chance to recover from a problem.

考虑代码的上下文也很重要。如果您正在编写具有大量 IO 的代码,那么您可能需要知道代码的哪些部分失败了。我在任何地方都没有看到 try...catch 旨在让您有机会从问题中恢复过来。

So if you get an IO exception in reading from one file, you may want to retry reading. Same with writing. But if you had one large try...catch you wouldn't know which to retry.

因此,如果您在读取一个文件时遇到 IO 异常,您可能需要重试读取。写作也是一样。但是,如果您进行了一次大尝试...捕获,您将不知道该重试哪个。

回答by Tom Anderson

I try to avoid duplication in catch blocks. If all the exceptions in a method receive the same treatment in the catch block, then go ahead and catch them all together. If you need to do different things with them, then catch them separately.

我尽量避免在 catch 块中重复。如果一个方法中的所有异常都在 catch 块中得到相同的处理,那么继续将它们一起捕获。如果你需要用它们做不同的事情,那就分别抓住它们。

For example, here we can catch all exceptions together, because any kind of exception means the whole method fails:

例如,这里我们可以一起捕获所有异常,因为任何类型的异常都意味着整个方法失败:

public PasswordAuthentication readAuthenticationDetails(File authenticationFile) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(authenticationFile));
        String username = reader.readLine();
        String password = reader.readLine();
        return new PasswordAuthentication(username, password.toCharArray());
    } catch (IOException e) {
        return null;
    }
}

Whereas here, we have different fallback behaviour for each group of calls, so we catch separately:

而在这里,我们对每组调用都有不同的回退行为,因此我们分别捕获:

public Collection<String> readServerHostnames(File mainServerConfigFile, File backupServerConfigFile) {
    String mainServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(mainServerConfigFile));
        mainServerHostname = reader.readLine();
    } catch (IOException e) {
        mainServerHostname = "default-server.example.org";
    }

    String backupServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(backupServerConfigFile));
        backupServerHostname = reader.readLine();
    } catch (IOException e) {
        backupServerHostname = "default-server.example.ru";
    }

    return Arrays.asList(mainServerHostname, backupServerHostname);
}

(This code exists purely to illustrate this point about catching exceptions; i beg you to disregard the fact that it is utterly horrible in other ways)

(此代码的存在纯粹是为了说明关于捕获异常的这一点;我恳求您忽略它在其他方面完全可怕的事实)