Questions tagged «exception-handling»

异常处理是对异常情况或需要特殊处理的异常情况做出响应的过程,通常会更改程序的正常执行流程。

8
例外:为什么要早丢?为什么要迟到?
关于隔离中的异常处理,有许多众所周知的最佳实践。我知道“做与不做”已经足够了,但是在大型环境中的最佳实践或模式方面,事情变得复杂了。“早点扔,迟到”-我已经听过很多次了,但仍然让我感到困惑。 如果在低层发生了空指针异常,为什么还要提早抛出并迟到?为什么要在更高层次上进行捕获?对于我来说,在较高级别(例如业务层)捕获低级异常对我来说没有任何意义。这似乎违反了每一层的关注。 想象一下以下情况: 我有一个计算数字的服务。为了计算图形,服务访问存储库以获取原始数据,并访问其他一些服务以准备计算。如果在数据检索层出现问题,为什么我应该将DataRetrievalException抛出更高级别?相反,我希望将异常包装为有意义的异常,例如CalculationServiceException。 为什么要早扔,为什么要迟到?


8
为什么使用try…最终没有catch子句?
经典的编程方式是使用try ... catch。什么时候适合使用try不catch? 在Python中,以下内容看起来合法且有意义: try: #do work finally: #do something unconditional 但是,代码没有catch任何内容。类似地,在Java中可能会认为如下: try { //for example try to get a database connection } finally { //closeConnection(connection) } 看起来不错,突然间我不必担心异常类型等。如果这是一种好的做法,那么什么时候才是好的做法?另外,为什么这不是良好做法或不合法?(我没有编译源代码。我正在询问它,因为它可能是Java的语法错误。我检查了Python是否确实可以编译。) 我遇到的一个相关问题是:我继续编写函数/方法,最后必须返回一些内容。但是,它可能位于不应该到达的地方,必须是返回点。因此,即使我处理了上面的异常,我仍会NULL在代码中某些不应该到达的位置(通常是方法/函数的结尾)返回或返回一个空字符串。我一直设法对代码进行重组,以使它不必一定要进行重组return NULL,因为这看起来绝对不像是一种好习惯。


3
为什么异常规范不好?
大约10年前回到学校时,他们正在教您使用异常说明符。由于我的背景是其中的一位Torvaldish C程序员,他们顽固地避免使用C ++(除非被迫这么做),所以我只会偶尔散布C ++,并且当我这样做时,我仍然使用异常说明符,因为这就是我所教的。 但是,大多数C ++程序员似乎并不喜欢异常说明符。我已经阅读了各种C ++专家的辩论和论点,例如这些。据我了解,它可以归结为三点: 异常说明符使用与其余语言不一致的类型系统(“影子类型系统”)。 如果您的带有异常说明符的函数抛出了除您指定的内容以外的其他任何内容,则该程序将以不良的意外方式终止。 即将在即将发布的C ++标准中删除异常说明符。 我在这里错过什么还是所有这些原因吗? 我个人的意见: 关于1):那又如何。就语法而言,C ++可能是有史以来最不一致的编程语言。我们有宏,goto /标签,未定义/未指定/实现定义的行为的部落(ho?),定义欠佳的整数类型,所有隐式类型升级规则,特殊情况下的关键字,例如friend,auto ,注册,显式...等等。有人可能会写几本关于C / C ++怪异故事的厚书。那么,人们为什么要对这种特殊的矛盾做出反应呢?与语言的许多其他更危险的特征相比,这是一个较小的缺陷? 关于2):这不是我的责任吗?我可以用C ++编写致命错误的方法有很多,为什么这种特殊情况会更糟?除了编写throw(int)然后抛出Crash_t之外,我还可以声明我的函数返回一个指向int的指针,然后进行一个狂野的,显式的类型转换,然后返回一个指向Crash_t的指针。C / C ++的精神始终是将大部分责任留给程序员。 那优势呢?最明显的是,如果您的函数尝试显式抛出除指定类型之外的任何类型,则编译器将给您一个错误。我认为有关此标准很明确。仅当您的函数调用其他函数而又抛出错误的类型时,才会发生错误。 来自确定性的嵌入式C程序世界,我当然希望更确切地知道函数会给我带来什么。如果有某种语言支持该功能,为什么不使用它呢?替代方案似乎是: void func() throw(Egg_t); 和 void func(); // This function throws an Egg_t 我认为在第二种情况下,调用者有很大的机会忽略/忘记实现try-catch,而在第一种情况下则更少。 据我了解,如果这两种形式之一决定突然引发另一种异常,则程序将崩溃。在第一种情况下,因为不允许它抛出另一个异常,在第二种情况下,因为没有人期望它抛出SpanishInquisition_t,因此该表达式不会在应有的位置被捕获。 如果是后者,在程序的最高级别进行一些最后的捕获似乎并没有比程序崩溃更好的方法:“嘿,程序中的某处引发了一个奇怪的,未处理的异常”。一旦远离异常引发的地方,您将无法恢复程序,唯一可以做的就是退出程序。 从用户的角度来看,如果他们从操作系统中收到一个错误消息框,说“程序终止。地址为0x12345的Blablabla”,或者从您的程序中获得一个错误消息框,指出了“未处理的异常:myclass。 func.something”。该错误仍然存​​在。 随着即将到来的C ++标准,我将别无选择,只能放弃异常说明符。但是,我宁愿听到一些可靠的论据,说明它们为什么不好,而不是“圣洁已经说过了,事实就是如此”。也许对他们的争论比我列出的要多,或者对他们的争论比我所意识到的还要多?

6
Java检查的异常的解决方法
我非常感谢有关lambda和默认方法接口的Java 8新功能。但是,我仍然对检查的异常感到无聊。例如,如果我只想列出对象的所有可见字段,我想简单地写一下: Arrays.asList(p.getClass().getFields()).forEach( f -> System.out.println(f.get(p)) ); 但是,由于该get方法可能会抛出一个与Consumer接口协定不同的已检查异常,所以我必须捕获该异常并编写以下代码: Arrays.asList(p.getClass().getFields()).forEach( f -> { try { System.out.println(f.get(p)); } catch (IllegalArgumentException | IllegalAccessException ex) { throw new RuntimeException(ex); } } ); 但是,在大多数情况下,我只希望将异常作为a抛出,RuntimeException并让程序处理或不处理没有编译错误的异常。 因此,我想就我对有争议的异常进行检查的方法发表您的看法。为此,我创建了一个辅助接口ConsumerCheckException<T>和一个实用程序功能rethrow(根据Doval的评论进行了更新),如下所示: @FunctionalInterface public interface ConsumerCheckException<T>{ void accept(T elem) throws Exception; } public class Wrappers { public static <T> Consumer<T> rethrow(ConsumerCheckException<T> c) …

8
为什么要设计一种没有异常处理机制的现代语言?
许多现代语言提供了丰富的异常处理功能,但是Apple的Swift编程语言没有提供异常处理机制。 像我一样,我陷入了异常,无法理解这意味着什么。Swift有断言,当然还有返回值。但是我很难想象我基于异常的思维方式如何映射到一个没有例外的世界(就此而言,为什么这样的世界是可取的)。有像Swift这样的语言我无法做的事情我可以做例外吗?通过丢掉异常我能获得一些收益吗? 例如,我如何最好地表达这样的话 try: operation_that_can_throw_ioerror() except IOError: handle_the_exception_somehow() else: # we don't want to catch the IOError if it's raised another_operation_that_can_throw_ioerror() finally: something_we_always_need_to_do() 缺少异常处理的语言(例如,Swift)?


8
是否有合理的理由返回异常对象而不是抛出异常对象?
该问题旨在适用于任何支持异常处理的OO编程语言。我使用C#仅出于说明目的。 通常会在出现无法立即处理代码的问题时引发异常,然后将异常捕获在catch其他位置的子句中(通常是外部堆栈框架)。 问:是否有任何合法的情况不会引发并捕获异常,而只是从方法中返回然后将其作为错误对象传递出去? 之所以提出这个问题,是因为.NET 4的System.IObserver<T>.OnError方法仅表明了这一点:异常作为错误对象传递。 让我们看看另一种情况,验证。假设我遵循传统的观点,因此我在区分错误对象类型IValidationError和ValidationException用于报告意外错误的单独异常类型: partial interface IValidationError { } abstract partial class ValidationException : System.Exception { public abstract IValidationError[] ValidationErrors { get; } } (System.Component.DataAnnotations名称空间的作用非常相似。) 这些类型可以按如下方式使用: partial interface IFoo { } // an immutable type partial interface IFooBuilder // mutable counterpart to prepare instances of above type { …

4
为什么要接住捕捉,必须使用方括号?
您可以使用多种语言(至少需要Java,也可以考虑使用C#吗?) if( condition ) singleStatement; while( condition ) singleStatement; for( var; condition; increment ) singleStatement; 因此,当我只有一条语句时,不需要使用添加新的作用域{ }。为什么我不能通过try-catch做到这一点? try singleStatement; catch(Exception e) singleStatement; 关于try-catch是否有一些特别之处,需要始终拥有新的作用域或其他内容?如果是这样,编译器无法解决该问题吗?

5
如何处理永远不会抛出的检查异常
例: foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1"); 由于编码是经过硬编码且正确的,因此构造函数将永远不会抛出规范中声明的UnsupportedEncodingException(除非Java实现被破坏,否则无论如何我都会迷路)。无论如何,Java仍然迫使我处理该异常。 目前看来 try { foobar = new InputStreamReader(p.getInputStream(), "ISO-8859-1"); } catch(UnsupportedEncodingException e) { /* won't ever happen */ } 任何想法如何使它变得更好?


4
最终在内部抛出异常
诸如Fortify之类的静态代码分析器会在一个finally块内抛出异常时说“抱怨” Using a throw statement inside a finally block breaks the logical progression through the try-catch-finally。通常我同意这一点。但是最近我遇到了以下代码: SomeFileWriter writer = null; try { //init the writer //write into the file } catch (...) { //exception handling } finally { if (writer!= null) writer.close(); } 现在,如果writer无法正确关闭,则该writer.close()方法将引发异常。应该抛出异常,因为(很可能是)写入后未保存文件。 我可以声明一个额外的变量,如果关闭时出错,则进行设置,writer并在finally块之后引发异常。但是这段代码可以正常工作,我不确定是否要更改它。 在finally块内引发异常的缺点是什么?

12
“尝试……抓住……最终”构造的“最终”部分是否必要?
某些语言(例如C ++和PHP的早期版本)不支持构造的finally一部分try ... catch ... finally。有finally必要吗?因为其中的代码始终运行,所以为什么不/不应该将代码放在try ... catch没有finally子句的块之后?为什么要用一个?(我正在寻找使用/不使用的原因/动机finally,不是取消“捕获”的理由,或者这样做的合法性。)

3
服务层是否应该捕获所有dao异常并将其包装为服务异常?
我有三层Spring Web应用程序:dao,服务和控制器。控制器从不直接调用dao,而是通过服务层进行调用。现在,大多数情况下,如果存在未处理的dao异常(运行时),则JSP将捕获该异常,并向最终用户显示错误消息。服务层是否应该捕获所有dao异常并将其包装为服务异常? try { daoInstance.someDaoMethod(); } catch(DataAccessException dae) { throw new ServiceException("message", dae); } 假设ServiceException也是运行时,并且也未处理。仅抛出DataAccessException而不是ServiceException有什么区别吗?我只是以为表示层不应该知道数据访问异常。但是我不认为捕获不可恢复的异常只是为了包装它们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.