有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java异常规范,是否有用?

第一个免责声明:这不是为了引起“语言战争”。我真的需要这个(关于这个问题的澄清)来写我的报告,我只想有有效和可靠的论据
好的,问题是:
在C++中,异常规范已经从C++ 11标准中删除,因为它被认为是造成伤害大于好处。br/> 另一方面,在Java中,异常规范被视为是好的、有用的东西
这两种语言中的这两个概念(拥有异常规范的目的)不同吗?这就是为什么这两个社区对这两个概念的看法不同,或者这两个概念相似/相同的原因
是哪一个?异常规范是好事还是坏事?还是因为Java(Java语言)在java中很好,(这里我想看到一些原因),C++中的(因为这里的原因)是不好的。br/> 感谢所有提供建设性帮助的人


共 (4) 个答案

  1. # 1 楼答案

    除了其他任何东西外,我认为java和C++异常规范之间的主要区别是java中,规范是函数类型的一部分,编译器强制你不能允许检查异常来逃避你的函数,除非它们是你的函数类型的一部分。p>

    因此,Java检查异常提供了一种有限/有缺陷的方法来跟踪哪些函数抛出了哪些异常。C++异常规范提供了一种限制/有缺陷的方法,防止调用函数抛出特定异常(或任何异常)。p>

    由于它们有不同的目的,因此必须分别评估它们的成功或失败。就实际程序员避免使用它们的程度而言,我认为您可以放心地说它们都有点失败,但这就是您可以用同样的方式对两者进行评估的全部内容。对于java来说,这个程度相当高,C++非常高。他们所拥有的有益的用途,以及在每种语言中的确切成功程度,是不同的

  2. # 2 楼答案

    爪哇和C++中的异常规范工作方式截然不同。p> <>这是C++的一个很好的信息来源。{a1}

    < C++设计的主要缺点是,如果你抛出一个意外的异常,你的程序很可能崩溃(参见细节的链接)。因此,异常规范是一个约束,它将应用得太晚

    Herb Sutter在文章结尾说:

    Moral #1: Never write an exception specification.
    
    Moral #2: Except possibly an empty one, but if I were you I’d avoid even that.
    

    java异常规范框架不同,您有两种类型的异常:检查(编译时)和运行时异常(非常类似C++,没有例外规范)。p>

    对于选中的异常,编译器将强制开发人员处理这些异常,否则应用程序将无法编译。这是好的和有用的,但是运行时和检查异常之间的区别并不完全清楚,这取决于开发人员,它可能会产生混淆。此外,即使使用简单的程序习惯用法(例如Checked exception specification and strategy pattern),检查的异常也涉及到困难的决策

    最终的结果是,像往常一样,由于没有明确的语言特征,它被错误地使用了。例如,C#设计师决定放弃它们

    我认为,在这个特定的主题上,java设计比C++03更好(我是C++的超级粉丝),因为它允许开发人员以更具描述性的方式编写更好的代码。然而,您需要花费精力(编码标准和代码审查)在您的开发团队中生成一致的代码

  3. # 3 楼答案

    多年前,Java的检查异常已经不再受欢迎,因为正如您所说的,它们造成的伤害大于帮助。如今,人们主要想办法避免它们,通常是用RuntimeException包装

    在有效的Java中,Josh Bloch仍然在“异常但预期的结果”的情况下为选中的异常进行辩护,但事实是,API编写者不是决定哪个结果是预期的,哪个不是的人。例如,在上下文中,即使是FileNotFoundException也可能是意外的、致命的结果

    所以,至少,任何公共图书馆都不应该使用检查过的异常

  4. # 4 楼答案

    C++和java在异常规范方面甚至是不可比的,因为它们在例外方面有不同:

    • C++仅在需要时使用动态分配,程序员尽可能多地使用堆栈分配(如果只是为了避免释放内存的问题)
    • Java几乎一直使用动态分配;对于用户定义类型的对象,对于数组(甚至是编译时已知大小的数组)
    在C++中,许多函数可以保证不会抛出任何异常。我不是在谈论异常规范,而是关于函数的记录和实际行为。对于简单函数调用的情况,只要没有可以引发异常的语句,异常规范是什么并不重要

    [对于从不抛出异常的函数,当调用需要测量函数异常的调用代码的调用代码时,异常规范才是重要的,以便调用中间非抛出函数,如果中间出现异常,将使对象处于坏状态。这是用^ {CD1>}完成的。在现代C++中,在旧C++中,这可以用更冗长的方式(也就是库之间不兼容)来完成。p>

    [注意:编译器始终有权查看编译期间可见的函数体,以确定是否可以抛出异常,并相应地优化调用代码(如果至少是为了减少异常表的大小)。抛出规范仅在编译器看不到代码无法抛出时才有帮助。]

    < C++ >此“永不抛出”要求可被文档化,并由编译器强制执行,并带有空抛出说明(无论是好的旧^ {< CD2>}还是现代^ {CD3>})。p>

    Java没有类似于这种极其有用的保证。它可以声明某些函数不抛出某些异常,这对于编写异常安全代码是无用的