文章标签 ‘异常处理’
看到了tangrui回应的文章,我想说的是,可能我们对于异常处理的理解有些地方是不一样的。 1. 我认为异常处理绝不是消息传递。这点在《Effective Java》中是明确说明的。因为如果简单地把Exception看成是另外一种返回值,代码会越来越混乱,也不符合Exception这个名词的含义。会让人看不懂,是非常不好的程序风格。(只能说是不好的程序风格,不是错误,因为编译器允许这样做) 2. 我认为RuntimeException和Checked Exception是有明显区别的。在Java中,所有非RuntimeException都是Checked Exception,而在C#中,完全没有区别。可以从字面上理解,RuntimeException是不可预知的异常,比如:NullPointerException(所有可预知的Null,都应该被避免了,剩下的都是不可预知的),BufferOverflowException(鬼知道什么时候会出现~),ArithmeticException(除数是零,永远不能是零的数,突然成了零),等等。而非RuntimeException,都是可以预知的。比如说,IOException(极有可能失败的操作),ClassNotFoundException(也是很有可能出现),InterruptedException(线程被中断,有可能),还有一切与应用逻辑相关的Exception等等。可以认为,如果发生了RuntimeException,那么这个异常必然不是预期可能出现的,都是不可恢复的。所有Checked Exception都是设计者可以预期的异常,大多数是可以恢复的。 3. 所有的RuntimeException都不应该被catch,而所有的Checked Exception都应该被catch。RuntimeException发生,说明程序有问题;Checked Exception发生,说明程序进入了一个可预知的意外情况。如果对于可预知的异常不作处理,那么这个问题是基本的coding问题,应该让编译器检查。 4. 一个接口所可能抛出的所有的Checked Exception都应该是接口设计的一部分。如果只有文档说明,这个风险太大了。很可能漏掉了很重要的异常问题没有处理。我希望可以由编译器来替我承担一部分风险。 所以,我并不是认为C#的方式非常的不好,只是认为,它为开发大型应用,带来了一定的风险。尤其是维护上的。而Java这种方式,非常严谨,在编译阶段为开发人员发现了很多有可能出现的潜在问题,虽然有可能会多写一些代码(其实这些代码是不多写的,无论用Java和C#,最终都是要写这些代码的)。至于tangrui说的,开发小程序可以快速上手的问题,我觉得不存在。因为如果真的是要成为优秀的开发人员,严谨的开发习惯是必须的,并不应该在乎异常处理所带来的麻烦。可以这么说,异常处理是开发过程中,非常重要的一部分。 这个问题我也就说到这里了,表达了我对异常处理的理解。我现在学习工作都要用C++,不能再像Java一样靠编译器了~hehe
刚看到tangrui同学的一篇文章,说Java与C#在异常处理上的区别。以前我们还是同事的时候,就一起讨论过这个问题,当时,我是极力的不满意C#的处理方式。这次看到这篇文章,有些给C#正名的意图,所以不得不说一说了。 首先还是声明一下,我不是大师,而设计Java与C#的都是大师,所以我并没有班门弄斧的意思,只是表达一下自己的观点和情感罢了。 对于Java和C#异常处理的区别,核心问题就是已知自定义类型的Exception是否应该在编译期检查。Java是强制检查,所有的接口定义都要声明自己要抛出哪些Exception,没有声明的绝对不能抛出(除RuntimeException外);C#是完全没有检查,任意接口都可以抛出任意类型的Exception。 通俗起见,我来举个例子:一把手枪,它有一个保险装置,在没有打开保险之前,扳机是不起作用的,当然,只要正确的将保险装置打开,就可以指哪打哪了;还有一把手枪,没有保险装置,但有一份很详细的说明书,告诉你这个东西有危险,有可能走火,小心点儿,以及如何正确使用并且避免走火,另外,作为附加,还给了你一块几平方分米防弹材料,建议你把它们放在走火的时候有可能打到的地方。那么,如果你是最终用户,你会选择哪把手枪呢?(需要说明的是,为了对比,我故意没有说,第一把手枪也有非常充分的说明书,但是很显然,不需要那不够用的防弹材料) 我觉得,Java就像是第一把手枪,C#像第二把手枪。 再从技术方面来说,几个问题: 1. 在设计一个接口的时候,是不是需要同时告诉用户,这个接口有可能抛出什么类型的Exception? 2. 如果需要,那么这个Exception类型是否应该成为一个接口声明的一部分? 3. 一个已知的有可能发生的exception被操作系统捕获是否可以说是用户在处理这个接口的声明的时候,出现了疏忽呢? 4. strong-type的目标是在编译器发现尽可能多的关于类型的错误,如果我们把接口的定义看作类型的一部分,那么是否可以说,这个有可能将checked exception暴露给操作系统的编译器在strong-type上有缺陷呢? 我的回答都是true。所以我觉得C#在strong-type上作的不够好。让用户不得不靠自己的记忆力以及本来就不太靠得住的细心来对付这些潜在的异常。 另外,我还有一个怀疑,就是C#是为了继承C++的异常处理方式,所以才放弃了Java的异常处理方式的。(只是怀疑,大家都知道,C++并不是strong type语言) 我对于编程语言并没有特别的偏好(也不允许有偏好,吃不饱的时候,就不挑食了),所以这里说的意思,只是说我觉得C#对于我这种懒得去背诵API的人来说,用起来不是很顺畅。








