代码如下:
public Response getABC(Request request) throws Exception {
Response res = new Response();
try {
if (request.someProperty == 1) {
// business logic
} else {
throw new Exception("xxxx");
}
} catch (Exception e) {
res.setMessage(e.getMessage); // I think this is weird
}
return res;
}
该程序运行正常。 我认为应该重新设计它,但是如何?
答案 0 :(得分:43)
除非在catch块中引发了其他异常,否则在try块中引发异常并立即对其进行捕获是没有意义的。
您的代码通过这种方式更有意义:
public Response getABC(Request request) {
Response res = new Response();
if (request.someProperty == 1) {
// business logic
} else {
res.setMessage("xxxx");
}
return res;
}
仅当您的业务逻辑(在条件为true
时执行)可能引发异常时,才需要try-catch块。
如果没有捕获到异常(这意味着调用者必须处理该异常),则可以不使用else
子句:
public Response getABC(Request request) throws Exception {
if (request.someProperty != 1) {
throw new Exception("xxxx");
}
Response res = new Response();
// business logic
return res;
}
答案 1 :(得分:15)
如果您从方法中抛出异常,那为什么还要麻烦捕获它呢?它要么返回带有“ xxxx”消息的响应,要么抛出异常,以供此方法的调用者处理。
"styles": [
"../node_modules/bootstrap/dist/css/bootstrap.min.css",
"../src/styles.css"
],
OR
public Response getABC(Request requst) {
Response res = new Response();
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}
return res;
}
答案 2 :(得分:8)
故意抛出异常然后直接捕获它似乎并不正确,
可以这样重新设计,
可以用throw new Exception("xxxx");
更改res.setMessage("xxxx");
,
然后可以保留捕获异常部分,以捕获业务逻辑内部可能发生的异常。
public Response getABC(Request requst) {
Response res = new Response();
try{
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}catch(Exception e){
res.setMessage(e.getMessage);
}
return res;
}
答案 3 :(得分:7)
首先,在重构工作方法时应特别小心,尤其是在执行手动重构时。也就是说,引入变量来保存message
可能是更改设计的一种方法:
public Response getABC(Request requst) throw Excetpions {
String message = "";
try{
if(request.someProperty == 1){
//business logic
else{
message = "xxxx";
}
}catch(Exception e){
message = e.getMessage();
}
Response res = new Response();
res.setMessage(message);
return res;
}
假设business logic
成功时是自己返回。
答案 4 :(得分:7)
我认为您可能会错过尝试/捕获的要点。该代码使用异常系统将任何异常消息冒泡给调用者。这可能位于嵌套调用堆栈的深处,而不仅仅是您正在查看的那个“抛出”。
换句话说,示例代码中的“ throws”声明正在利用此机制将消息传递给客户端,但是几乎可以肯定,它不是try / catch的主要目标用户。 (这也是一种草率,便宜的方式来传达此信息-可能会导致混乱)
无论如何,此返回值并不是一个好主意,因为异常通常没有消息,并且可以重新包装……总比没有好。异常消息并不是解决此问题的最佳工具,但是像这样从高层次处理异常仍然是个好主意。
我的意思是,如果您重构此代码,请确保查找可能在代码库中的任何地方抛出的运行时异常(至少在消息处理期间调用的任何地方),并且即使这样,您也可能应保持捕获/返回消息作为一个包罗万象,以防万一弹出意外的运行时异常。您不必将错误“ Message”作为响应的消息返回-可能有点“我们现在无法处理您的请求”,但请确保将堆栈跟踪信息转储到日志中。您目前正在扔掉它。
答案 5 :(得分:5)
为什么您已经抛出 Checked Exception 时为什么使用try / catch语句?
受检查的异常通常用于某些语言(例如C ++或Java),而不用于新语言(例如Kotlin)。我个人限制使用它。
例如,我有一个这样的课程:
class ApiService{
Response getSomething() throw Exception();
}
看上去很干净而且可读,但是破坏了异常处理机制的实用性。实际上,getSomething()
不会冒犯已检查的异常,但仍然需要像它一样行为吗?当ApiService上游有人知道如何处理这样的不可预测或不可预防错误时,此方法有效。并且,如果您真的知道如何处理它,请继续使用下面的示例,否则,未检查的异常就足够了。
public Response getSomething(Request req) throws Exception{
if (req.someProperty == 1) {
Response res = new Response();
// logic
} else {
thows Exception("Some messages go here")
}
}
我鼓励这样做:
public Response getSomething(Request req){
if (req.someProperty == 1) {
Response res = new Response();
// logic
return res;
} else {
return ErrorResponse("error message"); // or throw RuntimeException here if you want to
}
}
有关更多见解,由于多种原因,我之前提到的Kotlin
不支持已检查异常。
以下是JDK
类实现的StringBuilder
的示例接口:
Appendable append(CharSequence csq) throws IOException;
这个签名怎么说?它说每次我将字符串附加到某个内容(StringBuilder
,某种日志,控制台等)时,都必须捕获那些IOExceptions
。为什么?因为它可能正在执行IO
(Writer还实现了Appendable
)……所以它遍及整个地方都变成了这种代码:
try {
log.append(message)
}
catch (IOException e) {
// Must be safe
}
这不好,请参阅 Effective Java,第三版,条款77 :不要忽略异常。
看看这些链接:
答案 6 :(得分:3)
异常机制具有三个目的:
机制具有许多功能。为了使程序尽可能地简单(对于将来的维护者),因此,我们仅在确实需要时才使用此机制。
在您的示例代码中,我希望任何throw
语句都是一件非常严肃的事情,表明有问题,并且代码有望在某些地方处理这种紧急情况。在继续阅读该程序的其余部分之前,我需要先了解问题所在和严重程度。在这里,这只是String的幻想返回,我会挠头,想知道“为什么需要这样做?”而且本来可以花更多的精力。
因此,这段代码虽然不尽如人意,但只有在您也有时间进行完整测试的情况下,我才会对其进行更改。更改程序流程可能会引入细微的错误,如果需要修复任何问题,则需要立即进行更改。
答案 7 :(得分:3)
与如果要获取JVM在失败时返回的特定异常消息相同,那时候您可以在catch块中将try-catch与方法getMessage()或printStackTrace()一起使用。因此,您可以在此处修改代码:
public Response getABC(Request request) throws Exception {
Response res = new Response();
try {
if (request.someProperty == 1) {
// business logic
}
} catch (Exception e) {
res.setMessage(e.getMessage);
}
return res;
}