Questions tagged «exceptions»

例外是在应用程序过程中发生,需要偏离程序的正常流程。

7
为什么C ++中没有“最终”构造?
C ++中的异常处理仅限于try / throw / catch。与Object Pascal,Java,C#和Python不同,即使在C ++ 11中,该finally构造也尚未实现。 我已经看到很多有关“异常安全代码”的C ++文献。Lippman写道,异常安全代码是一个重要但高级而又困难的话题,超出了他的Primer的讨论范围-这似乎意味着安全代码不是C ++的基础。赫伯·萨特(Herb Sutter)在他的Exceptional C ++中为该主题投入了10章! 但是在我看来,如果finally实现了该构造,尝试编写“异常安全代码”时遇到的许多问题都可以很好地解决,从而使程序员可以确保即使在发生异常的情况下也可以恢复程序到安全,稳定,无泄漏的状态,接近资源分配和潜在问题代码的地步。作为一个经验丰富的Delphi和C#程序员,我使用try ..最终像大多数使用这些语言的程序员一样,在我的代码中广泛地进行了阻塞。 考虑到C ++ 11中实现的所有“风声”,我惊讶地发现“最终”仍然不存在。 那么,为什么finally从未在C ++中实现该构造呢?实际上,这不是一个很难理解或高级的概念,并且可以帮助程序员编写“异常安全代码”。
57 c++  exceptions 

12
捕获一般异常真的是一件坏事吗?
我通常同意大多数代码分析警告,并且我会坚持遵守。但是,我在这方面遇到了困难: CA1031:不捕获常规异常类型 我了解此规则的理由。但是,在实践中,如果无论是否引发异常,我都想采取相同的措施,为什么我要专门处理每一个?此外,如果我处理特定的异常,如果我正在调用的代码发生更改以在将来引发新的异常,该怎么办?现在,我必须更改代码以处理该新异常。而如果我只是抓住了Exception我的代码就不必更改。 例如,如果Foo调用Bar,并且Foo不管Bar抛出的异常类型如何都需要停止处理,那么具体确定我要捕获的异常类型是否有任何优势? 也许是一个更好的例子: public void Foo() { // Some logic here. LogUtility.Log("some message"); } public static void Log() { try { // Actual logging here. } catch (Exception ex) { // Eat it. Logging failures shouldn't stop us from processing. } } 如果您在此处未捕获到一般异常,则必须捕获所有可能的异常类型。帕特里克(Patrick)有一个优点,OutOfMemoryException不应以这种方式处理。那么,如果我想忽略所有例外情况OutOfMemoryException呢?
56 c#  design  exceptions 

9
引发异常或让代码失败
我想知道是否有反对这种风格的利弊: private void LoadMaterial(string name) { if (_Materials.ContainsKey(name)) { throw new ArgumentException("The material named " + name + " has already been loaded."); } _Materials.Add( name, Resources.Load(string.Format("Materials/{0}", name)) as Material ); } 对于每个方法,该方法name只能运行一次。_Materials.Add()如果同一对象将被多次调用,将抛出异常name。结果是我的后卫完全多余了,还是有一些不太明显的好处? 如果有人感兴趣,那就是C#,Unity。
52 exceptions 

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) …

4
为什么Python中的迭代器会引发异常?
这是Java中迭代器的语法(C#中的语法有点相似): Iterator it = sequence.iterator(); while (it.hasNext()) { System.out.println(it.next()); } 有道理。这是Python中的等效语法: it = iter(sequence) while True: try: value = it.next() except StopIteration: break print(value) 我认为例外应该只在特殊情况下使用。 为什么Python使用异常来停止迭代?

4
为什么方法不应该引发多种类型的检查异常?
我们使用SonarQube分析我们的Java代码,它具有以下规则(设置为关键): 公共方法最多应引发一个检查异常 使用检查的异常会强制方法调用者通过传播错误或通过处理错误来处理错误。这使得这些异常完全成为方法API的一部分。 为了使调用者的复杂度保持合理,方法不应抛出一种以上的检查异常。” 声纳的另一点是这样的: 公共方法最多应引发一个检查异常 使用检查的异常会强制方法调用者通过传播错误或通过处理错误来处理错误。这使得这些异常完全成为方法API的一部分。 为了使调用者的复杂度保持合理,方法不应引发超过一种检查异常。 如下代码: public void delete() throws IOException, SQLException { // Non-Compliant /* ... */ } 应该重构为: public void delete() throws SomeApplicationLevelException { // Compliant /* ... */ } 覆盖方法不受此规则检查,并允许引发多个检查的异常。 在阅读有关异常处理的文章时,我从没有遇到过这个规则/建议,也没有尝试找到有关该主题的一些标准,讨论等。我从CodeRach中发现的唯一东西是:一个方法最多应抛出多少个异常? 这是一个公认的标准吗?

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
异常传播:何时应捕获异常?
MethodA调用MethodB,然后依次调用MethodC。 在MethodB或MethodC中没有异常处理。但是在MethodA中有异常处理。 在MethodC中发生异常。 现在,该异常正在冒泡到MethodA,该方法可以适当地对其进行处理。 这有什么问题? 在我看来,在某个时候调用者将执行MethodB或MethodC,并且当这些方法中确实发生异常时,从这些方法内部处理异常中可以获得什么,这实际上只是一个try / catch / finally块,而不仅仅是让他们冒泡给被呼叫者? 围绕异常处理的陈述或共识是,仅在执行不能继续执行时抛出该异常。我明白了。但是,为什么不在链的更深处捕获异常,而不是让try / catch块一直向下传播。 当您需要释放资源时,我会理解的。完全是另一回事。

11
错误变量是反模式还是好的设计?
为了处理不应停止执行的几种可能的错误,我有一个error变量,客户端可以检查并使用该变量引发异常。这是反模式吗?有没有更好的方法来解决这个问题?有关此操作的示例,您可以查看PHP的mysqli API。假定正确处理了可见性问题(访问器,公共和私有范围,是类中的变量还是全局变量?)。

4
Python宽恕与权限和鸭子输入
在Python中,我经常听到“乞求宽恕”(捕获异常)比“询问许可”(类型/条件检查)更好。关于在Python中强制鸭子输入,这是 try: x = foo.bar except AttributeError: pass else: do(x) 胜过或坏于 if hasattr(foo, "bar"): do(foo.bar) else: pass 在性能,可读性,“ pythonic”或其他重要因素方面?

8
如果有意义的值超出范围,我应该抛出异常还是自己处理?
我写了一个表示纬度/经度坐标的结构。对于纬度,其值的范围是-180至180,对于纬度,其值的范围是90至-90。 如果该结构的用户给我提供的值超出该范围,则我有2个选择: 引发异常(arg超出范围) 将值转换为约束 因为坐标-185具有含义(因为极坐标可以很容易地将其转换为+175),所以我可以接受并转换它。 最好抛出一个异常来告诉用户他的代码给了我一个它不应该具有的值吗? 编辑:另外,我知道纬度/经度和坐标之间的区别,但是我想简化一下以便于讨论-这并不是最聪明的主意

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.