百科问答小站 logo
百科问答小站 font logo



Java设计出checked exception有必要吗? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

个人觉得这个和Java诞生的背景有关系。


Java语言是一个程序设计工程化的尝试,更少的选择,更标准的编写方式是Java的风格。在这个角度上来说,既然返回值类型是必须声明的,事实上异常也是一种返回值,声明可能返回的异常的类型也很合理。在语言层面上要求程序员对所有返回值(包括异常)进行明确的说明,摒除隐式的rethrow,这个思路是没有问题的。


当然实际运用中我们都知道这是个很失败的语言特性就对了。


user avatar   xing-jiankuan 网友的相关建议: 
      

简单来说,Checked Exception是个出发点很好,但是并没有什么卵用的设计。

说出发点很好,是因为我们都知道软件会有各种各样的问题,而严谨的处理这些问题会很好的提高软件的健壮性。Checked Exception的观点是让一个方法指定自己一定会抛什么异常,调用者必须决定一定要处理(catch),或者明确声明继续向上抛(throws)。那么整个程序对异常的处理就非常的明确了,程序员也有章可循,UT,测试也能很明确该处理什么错误。

但是,现实是骨感的。如果说比较接近底层的系统还能相对的设计出比较完备严谨的异常体系的,那么业务系统上这个干是严重吃力不讨好的。在业务系统中,一个典型的业务接口,有一个正常的处理结果,但是可能却有几十个不正常的情况发生。而Checked Exception要求必须每层调用,要不挨个处理,要不挨个声明往上抛。

挨个处理是不现实的,因为大部分情况下,大多数异常都是极端情况,平时很少出现,或者说即使出现了,影响也不大。比如,一个基金的详情,底层可能调用十几个不同的基金信息数据源(基本信息,经理,基金公司,费率,净值,重仓股……)。如果因为意外少个一个两个的,最好的办法是“软处理”。如果是必须使用Checked Exception的话,那么很多人都会这么干:

       try {   Fund fund = getFund(fundCode); } catch (SomeNotImportantButCheckedException e) {   // do nothing }     

程序员会用IDE自动产生出catch block但就是不处理。或者干脆:

       try {   Fund fund = getFund(fundCode); } catch (Exception e) {   // do nothing }     

这比不catch,自动往上抛更差。所以一般来讲,业务系统都会有个收底的错误处理,这个处理可能在业务系统的最高层。大部分不需要认真处理的异常往上抛。当真的意识到某个问题是个值得仔细处理下时,可能才会专门为它仔细的设计Exception和相应的处理。

挨个明确throws也是不现实的。一般我们看throws后边能挂3~4种Exception。按照上面的假设,可能要搞出几十种Exception,而且随着层级的提高这个数量会约堆越多。Java这里一般的建议是用类的体系来组织这些Exception,然后throws一个合适的基类。但我们都知道设计一个比较好的类体系是很困难的事情。更何况大多数异常都是不重要,收底处理的。为不重要的事情花费精力实在是不值当的,于是我们可以看到大家在这时基本上都会简化处理,变成直接用 Exception、 RuntimeException (连throws也不想用)或者自己封装一个“BizException”包装一下错误码和相关信息。

上面这些还都是在设计时可以定义所有异常的情况下遇到的问题。但在业务会剧烈变化的情况下,根本不可能一开始就预见所有可能的问题。强行加Checked Exception对于业务系统的接口来说,是不向前兼容的。如果一旦真的加上了,所有的调用方都会必须逼着跟着改。这种情况对于一个系统内部,一个code base可能还好处理。对于可能跨系统的调用(比如你写了一个java lib,别人用maven dependencies依赖),就可能是灾难性的。如果有某些组件因为种种原因无法升级,就不能使用新的代码。

因此,一个好的错误处理体系,最好能满足以下要求:

  • 不会逼着程序挨个处理无聊的异常,允许程序员有选择的把关注点放在哪些最关键的问题上。
  • 如果团队真的需要非常严谨的错误处理,可以提供一个有力的支持,但是这个支持是团队根据开发的内容来决定使用,而不是强制所有语言的使用者都必须遵循同一套“规则”。
  • 允许错误处理渐进性的发展

基于此,我在Team中对Java的异常是这么要求的:

  • 对于基础设施团队,需要使用Checked Exception,并且定义良好的异常继承体系,并且认真处理所有的异常。有限度的使用RuntimeException。
  • 对于业务团队,基于RuntimeException定义了一个BizException来描述各种业务问题,这个BizExcpetion包含了错误码和错误描述信息;同时定义InteralServerError来包装各种系统错误,比如网络超时等。在输出http response时,二者的输出不同,然后定义不同的监控和报警机制。
  • 针对特定的异常,由产品和技术共同商讨介入来设计
    • 哪些可以完全不管(比如一个不关键的数据拿不到),软处理;
    • 哪些要前端用户知晓和处理(比如登录时用户名或密码错误);
    • 哪些由程序尽量自己处理(比如关注某个产品超时,后端要尝试重试几次)

相信大多数团队也会这么做。

说完了Java,我们可以看看其他语言都是怎么处理异常的。比如go用了err(大致等价于错误码,但可以包含一些数据信息),因此异常可以不捕获往上抛的好处就得不到。因此这可以解释为什么很多搞底层系统开发的人并不会觉得go没Exception很难用,因为反正错误都需要严谨的处理,Exception那点优势可能不是很重要。但是即便如此,go并不会强制调用者必须处理写if err != nil 。

BTW,给go加上Exception的呼声似乎越来越强烈,估计是业务开发者越来越多了。

javascript也有Error,但是不是很喜欢搞继承体系。因此javascript里一般就只会用“Error”,“TypeError”这种简单的东西。因为动态语言,开发者可以选择自己往Error里赛自己喜欢的东西,并用一些松散的约定来解决问题。比如:

       throw Error("ERR_INVALID_PASSWORD");      

简单的用字符串来定义错误。javascript的主要应用场景在前端,这时出错要不给用户展示错误信息,要不用错误上报接口报给后端。复杂的异常体系基本没用,更谈不上什么Checked exception。

nodejs这边的exception处理可以借鉴很多java这边的经验。

kotlin直接砍掉了Checked Exception,但保留了其他常规的异常语法(改成了Expression,所以用起来爽很多)。他的文档直提供了两个论据:

swift更有趣,swift认为函数的异常模式有两种:

  • 会抛出异常的,于是函数名后边要声明一下“throws”,但是不需要声明会抛出什么异常;
  • 肯定不会抛出异常的,所以实现中必须吃掉各种可能发生异常的情况。

编译器会强制确保这个语义的正确。throws这种方式,大概等价于Java中直接throws Exception。

因此从工程角度和语言发展角度来讲,Checked Exception早已经被扔进了垃圾堆。在整个工程项目的错误处理体系里,它的作用已经越来越少。新的语言纷纷抛弃掉这个华而不实的设定。因此我也希望广大初学者只要知道Checked Exception是什么就好,实战时还是根据业务场景来设计错误处理。

--------

P.S. 也许还有人觉得Checked Exception是一种可以推进减少程序错误,提高健壮性的好措施。错的是懒惰的,不称职的程序员,而不是Checked Exception。但从我认为,如果一个措施不能有助于解决问题,反而加重问题,那就是无用的。不要把时间和精力浪费在无用的事物上。


user avatar   damon-dance-for-me 网友的相关建议: 
      

这两个游戏都有自己的问题。但严重程度完全不一样。

赛博朋克最大的问题是人力不够,没有人手把愿景在限期内做出来,导致后期狂砍。但从已有的成品来看,CDPR是完全有人才有能力把东西做出来的,只不过没时间做。光影效果,已有的垂直城市设计,以及主线和很多支线任务的演出都有毫不输巫师3的气质,尤其是日本城浮空平台那关,无论是游戏流程还是画面还是音乐,都把类似银翼杀手2047的那种气氛和感受做到了极致。有人说CDPR的人才都跑了,或者CDPR傲娇了开始放水,这并不客观。2077确实是个半成品,主机优化的问题尤其严重,但你关注已经完成的部分,用高配置PC玩,其质量并未令人失望,依然是巫师3的水准。

2077就像是一个优等生忘了做背后的几题的考卷,开天窗导致不及格,但已经做了的题目还是正确率极高的。

谈到E3的demo,单从画面上讲你很难说它缩水了。只不过CDPR没告诉你想要E3画面,就得上3080+光线追踪。。。

我猜想没有光追的话,游戏在大多数情况下也是可以达到光追的效果的,只不过人工工作量会很大,有些地方需要离线烘培,而有些地方需要人工设置虚拟光源。CDPR可能发现项目后期工作量太大搂不住了,就上了光追这个大杀器。。。


至于无人深空,现在口碑很好,但我要不客气地讲,这个游戏到了今天依然是垃圾,只配卖$19.95,打折的时候卖2.95的那种。

Hello工作室自始自终都没有把初始愿景实现的技术能力。

你可以看无人深空进入大气层的技术实现。先是一段飞船进入大气层摩擦发红的特效,然后可以看见地形通过一种非常粗糙、视距很近的情况下刷新出来,并且刷出来的地貌和太空中看到的地貌完全不同。所以从头到尾,hello工作室都没有类似精英危险和星际公民的无缝行星登陆技术。

无人深空更新了十几次,并没有触动这个游戏除了机械刷就没有任何深度的本质。这是一个极其无聊的游戏。但它刷了两年的DLC,玩家也就给他点面子,没功劳有苦劳。它每次更新我都会进游戏看看,但玩不了半小时就会放弃。一是实在无聊,二是它美术设计和渲染水平有限,色彩及其刺眼。比如在母船机库里,到处都是亮瞎狗眼的点状光源,但这些光源不会照亮周围的任何东西,看的时间长了有种不带护目镜看焊接的流泪效果。你说更新了那么久,这么简单的问题都不解决,有什么用呢。游戏中随处可见低级设计的痕迹,比如说有很多行星上有一种可以卖钱的球,这种球没有任何贴图,只有亮瞎眼的纯白色材质,在HDR效果下极其刺眼,但它又不是个光源,放在地上不会照亮周围任何东西。这种打开Blender就存盘的建模初手垃圾素材居然也能放在游戏里,真是活久见。

所以无人深空就像是一个学渣冒充学霸,把期望提得无限高,却每题都答错结果接近0分,被骂,然后花了漫长的时间在那里订正,一题一题的改,最后终于接近30分了,然后获得了大家的赞赏,全然忘记了它改了那么久依然是不及格。

无人深空的贴图我就不贴了,首发的时候真是纯垃圾,基本上是2008年魔兽世界首发的那个水准。现在也依然是垃圾,开个HDR看着眼睛都疼。


user avatar   catchen 网友的相关建议: 
      

这两个游戏都有自己的问题。但严重程度完全不一样。

赛博朋克最大的问题是人力不够,没有人手把愿景在限期内做出来,导致后期狂砍。但从已有的成品来看,CDPR是完全有人才有能力把东西做出来的,只不过没时间做。光影效果,已有的垂直城市设计,以及主线和很多支线任务的演出都有毫不输巫师3的气质,尤其是日本城浮空平台那关,无论是游戏流程还是画面还是音乐,都把类似银翼杀手2047的那种气氛和感受做到了极致。有人说CDPR的人才都跑了,或者CDPR傲娇了开始放水,这并不客观。2077确实是个半成品,主机优化的问题尤其严重,但你关注已经完成的部分,用高配置PC玩,其质量并未令人失望,依然是巫师3的水准。

2077就像是一个优等生忘了做背后的几题的考卷,开天窗导致不及格,但已经做了的题目还是正确率极高的。

谈到E3的demo,单从画面上讲你很难说它缩水了。只不过CDPR没告诉你想要E3画面,就得上3080+光线追踪。。。

我猜想没有光追的话,游戏在大多数情况下也是可以达到光追的效果的,只不过人工工作量会很大,有些地方需要离线烘培,而有些地方需要人工设置虚拟光源。CDPR可能发现项目后期工作量太大搂不住了,就上了光追这个大杀器。。。


至于无人深空,现在口碑很好,但我要不客气地讲,这个游戏到了今天依然是垃圾,只配卖$19.95,打折的时候卖2.95的那种。

Hello工作室自始自终都没有把初始愿景实现的技术能力。

你可以看无人深空进入大气层的技术实现。先是一段飞船进入大气层摩擦发红的特效,然后可以看见地形通过一种非常粗糙、视距很近的情况下刷新出来,并且刷出来的地貌和太空中看到的地貌完全不同。所以从头到尾,hello工作室都没有类似精英危险和星际公民的无缝行星登陆技术。

无人深空更新了十几次,并没有触动这个游戏除了机械刷就没有任何深度的本质。这是一个极其无聊的游戏。但它刷了两年的DLC,玩家也就给他点面子,没功劳有苦劳。它每次更新我都会进游戏看看,但玩不了半小时就会放弃。一是实在无聊,二是它美术设计和渲染水平有限,色彩及其刺眼。比如在母船机库里,到处都是亮瞎狗眼的点状光源,但这些光源不会照亮周围的任何东西,看的时间长了有种不带护目镜看焊接的流泪效果。你说更新了那么久,这么简单的问题都不解决,有什么用呢。游戏中随处可见低级设计的痕迹,比如说有很多行星上有一种可以卖钱的球,这种球没有任何贴图,只有亮瞎眼的纯白色材质,在HDR效果下极其刺眼,但它又不是个光源,放在地上不会照亮周围任何东西。这种打开Blender就存盘的建模初手垃圾素材居然也能放在游戏里,真是活久见。

所以无人深空就像是一个学渣冒充学霸,把期望提得无限高,却每题都答错结果接近0分,被骂,然后花了漫长的时间在那里订正,一题一题的改,最后终于接近30分了,然后获得了大家的赞赏,全然忘记了它改了那么久依然是不及格。

无人深空的贴图我就不贴了,首发的时候真是纯垃圾,基本上是2008年魔兽世界首发的那个水准。现在也依然是垃圾,开个HDR看着眼睛都疼。


user avatar   ikkiz-70 网友的相关建议: 
      

我觉得应该派解放军去保护我们的自由贸易权力,如果英国人不肯的话就打进白金汉宫,火烧温莎堡




  

相关话题

  Kotlin 作为 Android 开发语言相比传统 Java 有什么优势? 
  为什么有很多人执着于中文编程? 
  我在编程时给变量命名总觉得困难,有没有什么实用技巧? 
  低代码开发以后有前景么?会不会最后一地鸡毛? 
  可以用 Python 编程语言做哪些神奇好玩的事情? 
  C「带坏了」多少程序语言的设计? 
  如果一瞬间让所有编程语言的0.1 + 0.2 == 0.3,会造成多大影响? 
  这篇博文c#比JAVA慢这么多 为什么? 
  如何通俗地理解「分布式系统」,它解决了哪些问题,有什么优缺点? 
  编译器怎么处理定义但未使用的函数? 

前一个讨论
如何评价前Google雇员发文认为员工有权不与公司同流合污?
下一个讨论
微软现在是不是真的到了离倒闭只有18月的时刻了?





© 2024-11-21 - tinynew.org. All Rights Reserved.
© 2024-11-21 - tinynew.org. 保留所有权利