深入理解try-catch-finally-return的执行顺序与返回值

5星 · 超过95%的资源 需积分: 41 6 下载量 14 浏览量 更新于2024-09-05 收藏 77KB DOC 举报
本文档详细探讨了Java编程中`try-catch-finally`语句块的执行顺序以及`return`语句在其中的作用。首先,重要的一点是无论是否发生异常,`finally`块中的代码始终会被执行,确保其中的清理工作得以完成。即使`try`和`catch`部分有`return`语句,`finally`也会按照预期执行。 1. **finally的执行**: - 当没有异常时,程序执行顺序为:try -> finally -> return。这意味着`finally`块在返回值计算之前执行,但它并不参与返回值的决定,而是保留了`try`块中`return`语句原有的返回值。 2. **带有return的try和catch**: - 情况1:`try{}catch(){}finally{}return;`:整个程序按顺序执行,先try,后finally,最终返回。 - 情况2:`try{return;}catch(){}finally{}return;`:先执行`try`块中的`return`,然后执行finally,但finally中的`return`不会被执行,因为try中的`return`已结束程序流程。 3. **处理异常的catch与return**: - 情况3:`try{}catch(){return;}finally{}return;`:异常发生时,执行catch块中的`return`,然后finally块执行,最终是catch块的返回值占据主导。 - 无异常时,程序流程为:try -> finally -> return。 4. **混合return的finally**: - 情况4:`try{return;}catch(){}finally{return;}`:先执行try中的`return`,然后执行finally,如果finally内有`return`,则执行finally的返回值,取代try的返回值。 5. **总结**: - `finally`块的`return`仅在特定情况下起作用,如覆盖前面的`return`语句,特别是当异常发生或`catch`中有`return`时。 - 对于基本数据类型,如整型、字符型等,`finally`对返回值的影响是间接的,因为它们是按值传递的。但对于引用类型(如列表、映射和自定义类实例)、对象,由于是按地址传递,`finally`内的修改会影响返回的结果。 通过这些示例,理解了在处理异常和`return`语句时,`try-catch-finally`结构的执行细节至关重要。开发者在编写代码时,需要考虑到这些规则以确保程序的正确性和预期行为。

给这个方法添加单元测试: public String cloneMessage(CisMonitorData data){ log.info("Starting process to clone and publish message to queue for request id {}", data.getTdsStpId()); CisPubTds cisPubTds = monitorDao.getTdsPubRequestById(data.getTdsStpId()); if(cisPubTds == null){ return CisTStpConstants.MSG_1; } if(cisPubTds.getMessage() == null){ return CisTStpConstants.MSG_2; } if(data.getUser() == null){ return CisTStpConstants.MSG_18; } if(data.getComment() != null && data.getComment().length() > 250){ return CisTStpConstants.MSG_19; } String status = null; try { CisPubTds clonePubTds = (CisPubTds)cisPubTds.clone(); clonePubTds.setTdsStpId(null); clonePubTds.setCreatedDate(new Date()); clonePubTds.setCreatedBy(data.getUser()); clonePubTds.setIsStpEd(0); clonePubTds.setStpEdAt(null); clonePubTds.setUserComment(data.getComment()); clonePubTds = monitorDao.saveOrUpdatePubTds(clonePubTds); if(clonePubTds != null && clonePubTds.getTdsStpId() != null && clonePubTds.getTdsStpId() > 0) { log.info("Updating the XML message for cloned request with new TDS STP id : {}", clonePubTds.getTdsStpId()); /Update tracking ID in SCBML message and save it to database/ Document doc = DocumentUtility.StringToDocument(clonePubTds.getMessage()); DocumentUtility.updateNodeValue(doc, clonePubTds.getTdsStpId()); String updatedXml = DocumentUtility.DocumentToString(doc); clonePubTds.setMessage(updatedXml); clonePubTds = monitorDao.saveOrUpdatePubTds(clonePubTds); /End/ log.info("Update of the XML message for cloned request with new TDS STP id : {} is completed", clonePubTds.getTdsStpId()); log.info("Publishing the cloned message"); boolean statusBool = publish(clonePubTds); if(statusBool){ status = CisTStpConstants.MSG_SUCCESS; } log.info("End of publish with statusBool : {}", statusBool); log.info("End of publish with status : {}", status); }else { status = CisTStpConstants.MSG_8; } log.info("End process to clone and publish message to queue for request id {}", data.getTdsStpId()); } catch (CloneNotSupportedException e) { status = CisTStpConstants.MSG_7; log.error("Error while cloning the object {}", e); } catch (Exception e) { log.error("Error while creating object {}", e); } return status; }

2023-06-07 上传