多年来,我一直无法得到以下问题的正确答案:为什么一些开发人员如此反对已检查的异常?我有很多对话,在博客上阅读,阅读Bruce Eckel所说的内容(我看到的第一个人反对他们).
我目前正在编写一些新代码,并非常注意我如何处理异常.我试图看到"我们不喜欢被检查的例外"人群的观点,我仍然看不到它.
每次谈话结束时,同样的问题都没有得到答复......让我把它设置起来:
一般来说(从Java的设计方式来看),
我听到的一个常见论点是,如果发生异常,那么开发人员将要做的就是退出该程序.
我听到的另一个常见论点是,经过检查的异常会使重构代码变得更加困难.
对于"我将要做的就是退出"这个论点,我说即使你要退出,你也需要显示一个合理的错误信息.如果您只是在处理错误,那么当程序退出而没有明确说明原因时,您的用户将不会过于高兴.
对于"它很难重构"的人群,这表明没有选择适当的抽象级别.而不是声明方法抛出IOException,IOException应该转换为更适合正在发生的事件的异常.
我没有使用catch(Exception)包装Main的问题(或者在某些情况下catch(Throwable)以确保程序可以正常退出 - 但我总是捕获我需要的特定异常.这样做允许我,至少,显示适当的错误消息.
人们从不回复的问题是:
如果你抛出RuntimeException子类而不是Exception子类,那么你怎么知道你应该捕获什么?
如果答案是捕获异常,那么您也会以与系统异常相同的方式处理程序员错误.这对我来说似乎不对.
如果您捕获Throwable,那么您将以相同的方式处理系统异常和VM错误(等).这对我来说似乎不对.
如果答案是你只捕获你知道的异常,那么你怎么知道抛出的是什么?当程序员X抛出一个新的异常并忘记捕获它时会发生什么?这对我来说似乎非常危险.
我会说显示堆栈跟踪的程序是错误的.那些不喜欢检查异常的人是不是觉得那样?
那么,如果您不喜欢已检查的异常,您可以解释为什么不能并且回答那些无法解答的问题吗?
编辑:我不是在寻找何时使用任何一个模型的建议,我正在寻找的是为什么人们从RuntimeException扩展,因为他们不喜欢从Exception扩展和/或为什么他们捕获异常然后重新抛出RuntimeException而不是将抛出添加到他们的方法中.我想了解不喜欢检查异常的动机.
我需要检查一些值是否为null.如果它不为null,那么只需将一些变量设置为true即可.这里没有其他声明.我得到了太多像这样的条件检查.
有没有办法处理这个空检查而不检查所有方法返回值?
if(country != null && country.getCity() != null && country.getCity().getSchool() != null && country.getCity().getSchool().getStudent() != null .....) {
isValid = true;
}
Run Code Online (Sandbox Code Playgroud)
我想直接检查变量并忽略NullpointerException.这是一个好习惯吗?
try{
if(country.getCity().getSchool().getStudent().getInfo().... != null)
} catch(NullPointerException ex){
//dont do anything.
}
Run Code Online (Sandbox Code Playgroud) 我是从C++来的Java.在C++世界中,我们注意异常安全,并注意,mutator可以在mutator本身抛出的异常或它委托给它的方法(最小,强,无抛出)时提供不同的保证.实现具有强异常保证的方法需要保证一些基本操作永远不会抛出异常.JLS声明哪些操作可以抛出哪种异常,但VirtualMachineError
错误会带来问题.答曰JLS:
内部错误或资源限制阻止Java虚拟机实现Java编程语言的语义; 在这种情况下,
VirtualMachineError
抛出一个子类的实例 .
JLS没有再说了VirtualMachineError
."内部错误"意味着JVM中的一个错误,所以我对这种情况不感兴趣:面对JVM中的错误,所有的赌注都是关闭的.但是那个"资源限制"案例呢?是否存在因资源限制而保证永不失败的操作?
昨天我从假期回来工作,在我们的日常站立中,我的队友们提到他们正在重构我们的java代码中的所有模型对象以删除所有的getter和setter,并使模型字段成为所有公共对象,调用Law of Law德米特之所以这样做是因为
为了方便我们遵守得墨忒耳定律:模块不应该知道它操纵的"物体"的内部.由于数据结构不包含任何行为,因此它们自然会暴露其内部结构.因此,在这种情况下,德米特不适用.
我承认我必须了解我对LoD的了解,但对于我的生活,我找不到任何迹象表明这符合法律的精神.我们模型中的getter/setter都不包含任何业务逻辑,这是他这样做的理由,因此这些对象的客户端无需了解是否在get/set方法中执行了某些业务逻辑.
我认为这是对需要"对象结构的内部知识"意味着什么的误解,或者至少在字面意义上并且在这个过程中打破了一个非常标准的约定.
所以我的问题是,直接暴露模型对象内部结构而不是通过LoD名称中的getter/setter实际上是否有意义?
我正在使用旧版应用程序,在该应用程序中,我经常不得不访问像下面这样嵌套的属性:
a.getB().getC().getD().getE().getF()
Run Code Online (Sandbox Code Playgroud)
问题在于,在任何深度下,该值都可能为空。当然,我可以像这样检查每个深度:
public Optional<F> retrieveValue(A a) {
if(a != null && a.getB() != null && a.getB().getC() != null &&
a.getB().getC().getD() != null &&
a.getB().getC().getD().getE() != null &&
a.getB().getC().getD().getE().getF() != null) {
return Optional.of(a.getB().getC().getD().getE().getF());
} else {
return Optional.empty();
}
}
F existingOrCreated = retrieveValue(a).orElse(new F());
Run Code Online (Sandbox Code Playgroud)
但是我必须在许多地方对许多不同的对象执行此操作,因此这些检查会使代码膨胀。大多数情况下,对象不是非null,但是在少数情况下,对象为null。有没有一种更简洁的方法?我正在使用Java 8,但是无法更新提供的旧代码。
不像C或C++,如果Java中的任何一个对象(A,B)都为null ,o = objectA.objectB.objectC
则抛出一个NullPointerException
.在Java 1.7中,我无法执行任何像lambda表达式这样的命令来运行带try-catch
保护的命令.
那么,你将如何完美地缓存异常呢?
我有一个类结构,如
Class A {
int val;
}
Class B {
A a;
}
Class C {
B b;
}
Run Code Online (Sandbox Code Playgroud)
现在,所有类都来自第三方服务,我从中获得响应,我想读取int值.但我不想做类似的事情
假设c是C类型的变量.
if (c != null && c.getb != null) {
B b = c.getb()
and so on.
}
Run Code Online (Sandbox Code Playgroud)
我想避免这些空检查,因为实际上这些pojos是非常分层的并且在它们中有很多字段.
我试过用
Optional<Integer> val = Optional.ofNullable(c.getb().geta().getval());
val.elseThrow(Ex::new)
Run Code Online (Sandbox Code Playgroud)
但这不是正确的方法(如果b不存在则抛出空指针异常,因为int上是可选的).我怎么办才能解决这样一种情况,即我无法控制Pojos的声明,但又想避免牛市检查?
我有一个对象,我想检查此对象或嵌套字段是否为空.我想打印这个neted字段,但我应该检查某个级别是否有null,否则我将获得空指针异常.
我知道我可以这样做:
if( object != null && object.A != null && object.A.B != null && object.A.B.C != null && object.A.B.C.D != null) { doSomething( object.A.B.C.D);}
Run Code Online (Sandbox Code Playgroud)
但它太久了.你知道更好的检查方法吗?
我有以下嵌套的空检查。试图通过使其可读,Optional
但如何映射第一个元素?
卡在下面,不确定如何映射这条线
vo.getSomething().getAnother().get(0)
Run Code Online (Sandbox Code Playgroud)
我被困在三号线
Optional.of(vo.getSomething)
.map(Something::getAnother)
.map(List<Another>::get(0)) // will not work
Run Code Online (Sandbox Code Playgroud)
这是一个有效的空检查。我正在尝试使用Optional清理它。
if(vo.getSomething() != null){
if(vo.getSomething().getAnother() != null){
if(vo.getSomething().getAnother().get(0) != null){
if(vo.getSomething().getAnother().get(0).getInner() != null){
if(vo.getSomething().getAnother().get(0).getInner() != null){
if(vo.getSomething().getAnother().get(0).getInner().get(0) != null){
return vo.getSomething().getAnother().get(0).getInner().get(0).getProductName();
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试在抛出 NullPointerException 的 getter 上使用 Optional.ofNullable :
我的代码如下:
Individual individual = null;
Optional.ofNullable(individual.getIndividualName());
Run Code Online (Sandbox Code Playgroud)
在这里抛出 NullPointerException 是正常的,因为个人为空
我想找到一种很好的方法来避免此异常并获得 null 作为结果
Optional.ofNullable(individual.getIndividualName());
Run Code Online (Sandbox Code Playgroud)
Null 检查链与捕获 NullPointerException 中的解决方案非常繁重。我在 jUnit 测试中尝试并需要几秒钟才能得到结果!