HardConcrete 2023-06-10 23:36 采纳率: 0%
浏览 119
已结题

论接口/特征方法不设计错误返回带来的问题,以及为什么很多标准接口/特征方法不设计错误返回

-->在编程中常有重写方法、为方法特供自己特有的实现的情况,例如子类重写父类非抽象方法、实现类实现接口(java的interface)、实现特征(rust的trait)等。
-->
--> 而一个子模块的方法中如果遇到一些可预料的错误:如用户输入不合法、文件不存在等错误,一般是需要将这个错误反馈给上层处理。而不应该是自己擅自主张直接进入panic恐慌模式来终止程序或者线程
-->
!!!【本问题不讨论编程错误引起的错误情况:如数组越界访问,使用悬垂引用、NPE等,在java的语境中,”错误“一词没有特殊说明,不表示java中的Error类】
-->
-->不同语言特供了自己的方式来反馈错误。在java中常用受检异常来抛出这种异常又或者用是Optional,而C和rust都偏向与使用返回值来反馈这种异常(rust中,返回Result<T, E>或Option)。这些反馈错误的方式往往就表示在方法的签名中。
-->
-->一种重现父类方法的方法它往往是根据自己的业务有自己的实现方式,而这是实现方式决定了这个方法是否会抛出异常和会抛出哪些异常。作为一个父类方法、接口方法或者trait方法它的函数签名是静态的,也就是说它是否会反馈错误,怎么反馈错误都是写死固定的。同时这些父类方法、接口方法或者trait方法,也不能确定使它们被重写的方法是否会抛出错误和会抛出哪些错误,那如果说这些父类方法、接口方法或者trait方法如果要能支持重写方法能抛出自己的与业务相干的错误。那所有的父类方法、接口方法或者trait方法难道不应该都要在签名中设计错误的反馈方式吗?但是很显然,许多标准库/包中的接口和trait并没有这么做,很多方法签名上根本没有涉及任何的错误返回方式,这是为什么呢?这样做不就是在限制具体实现的功能吗?因为不能反馈错误,所以所有可能出错的实现都不能重写那些父类方法、接口方法或者trait方法,这个限制实在令人太失望了。
-->
-->在java中有些人会建议使用RuntimeException去包装这些错误然后再抛出,这样方法签名就可以不用写明这个错误,就和接口方法(父类方法)的签名达成一致。但是我认为这个方法真是太糟糕了,令人头皮发麻。因为接口方法(父类方法)的文档是不会说明这些实现方法(重写方法)可能犯下的具体错误的,其他方法在使用这个接口方法(父类方法)是无法知道会出现什么错误的,因此使用这个接口方法(父类方法)的方法会出现什么样错误也是未知,这给人感觉就像程序的任何一个函数都会出现错误,并且还不知道它的具体错误类型,正如开头所说的那样,他是程序运行中会出现的正常情况,因此我们应该要求程序去处理这种错误,但是上层的代码要处理这些错误要先知道哪会发生错误和有哪些错误。但是使用RuntimeException去包装这些错误后,这个问题就难以回答了。如果有人尝试经过认真的分析程序中所有被RuntimeException包装的错误的源头和传播路径(这必然要深入了解方法的具体实现),在上层的代码中找到了所有可能会出现这些错误的范围,那真是一件辛苦的事,但是更可怕的是,如果在将来又有一些新的RuntimeException包装的错误的源头出现或者消失,那么上层的代码中可能会出现这些错误的范围又将会改变,你又要重新小心翼翼地去分析一遍这些错误的传播路径,这真是一件非常不愉快的事情。为了削弱这种耦合,有的人可能就直接将上层代码整个都泡在try-catch块中,防止有漏网之鱼,想想就太疯狂了,这让我不禁怀疑自己是不是不应该这样写代码。
-->
-->换做其他语言,可能就不能像java这样做到用RuntimeException包装错误然后丢到上层处理了,所以这不是一个广泛适用的办法,更何况这个办法本来就很鸡肋,RuntimeException一般也不是用于这类错误的,它本应该对应的是造成以恐慌模式结束程序或者线程的错误。
-->
总结问题如下:
-->我已经分析了父类方法、接口方法或者trait方法不设计错误返回的签名的危害,现在第一个问题是为什么很多标准库中的接口/特征方法不设计错误返回或者只设计了它感兴趣的错误返回?
-->
-->如果你觉得(标准库)它们这么做是合适的,那么第二个问题就是怎么判断父类方法、接口方法或者trait方法要不要设计让实现方法/子类方法设计返回任何错误的类型的签名,以及怎么处理当实现方法/子类方法确实需要返回超过父类方法、接口方法或者trait方法签名声明的错误范围的情况。

  • 写回答

7条回答 默认 最新

  • Jackyin0720 2023-06-11 08:39
    关注
    获得6.25元问题酬金

    你这文字描述太多,其实就一个重点,或者姑且算是一个讨论议题。
    结论:在设计接口或特征方法时,需要判断是否需要设计异常错误返回。
    通常情况下,如果接口或特征方法执行过程中可能出现异常或错误,并且该异常或错误会对调用方产生影响,那么就需要设计异常错误返回。例如,在编写一个文件读取方法时,如果文件不存在或无法读取,就需要设计异常错误返回,以便调用方能够捕获并处理该异常。然而,在设计接口或特征方法时,也需要考虑异常错误返回对方法性能的影响。如果异常错误返回过于频繁,可能会影响方法的执行效率。因此,在设计异常错误返回时,需要权衡方法的性能和可靠性。
    因此,在设计接口或特征方法时,需要根据方法的实际需求和场景来判断是否需要设计异常错误返回。如果方法执行过程中可能出现异常或错误,并且该异常或错误会对调用方产生影响,那么就需要设计异常错误返回。

    评论

报告相同问题?

问题事件

  • 系统已结题 6月18日
  • 修改了问题 6月14日
  • 修改了问题 6月13日
  • 修改了问题 6月11日
  • 展开全部

悬赏问题

  • ¥30 自适应 LMS 算法实现 FIR 最佳维纳滤波器matlab方案
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥15 Python3.5 相关代码写作
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像