受检异常
非受检异常
try{ int i = 0; while(true) { range[i++].climb(); } } catch (ArrayIndexOutOfBoundException e) { } 复制代码
// 语法糖 for (Mountain m : range) { m.climb(); } // 等同于 for (int i = 0; i < rang.length; i++) { rang[i].clmib(); } 复制代码
常用的异常如下:
异常 | 使用场合 |
---|---|
IllegalArgumentException | 非null的参数值不正确 |
IllegalStateException | 对于方法调用而言,对象状态不合适 |
NullPointerException | 在禁止使用null的情况下参数值为null |
IndexOutOfBoundsException | 下标参数值越界 |
ConcurrentModificationException | 在禁止并发修改的情况下,检查到队形的并发修改 |
UnsupportedOperationException | 对象不支持用户请求的方法 |
/** * 字符串 转 UUID * 字符串格式为不带-的32位字符串 * * @param uuidString * @return */ public static UUID format(String uuidString) { if (uuidString.length() != 32) { throw new IllegalArgumentException("Invalid UUID string: " + uuidString); } // ... } 复制代码
try { ... // user lower-level abstraction to do out bidding } catch (LowerLevelException e) { throw new HigherLevelException(...); } 复制代码
/** * 创建meeting的对象 * * @param meetingCreateForm * @return * @throws InterruptedException 未进行说明什么条件下会发生该异常,让调用方产生疑惑 */ private Meeting buildMeeting(MeetingCreateForm meetingCreateForm) throws ParseException { } 复制代码
public ContactPersonView add(UUID userId, ContactPersonCreateForm contactPersonCreateForm) { UserInfoView userInfo = userClientRemote.getUserInfo(contactPersonCreateForm.getId()); if (userInfo == null) { throw new RestException(ErrorCode.NOT_FOUND, "user not found"); } // ... } 复制代码
public Object pop() { // 当栈的大小为0,没有元素可以出栈,则进行抛出异常,防止栈被修改 if (size == 0) { throw new EmptyStackExcpetion(); } Object result = element[--size]; element[size] = null; return result; } 复制代码
// 1、查库存 Store beforeStore = storeDao.findByProductId(productId); Store afterStore = new Store(); // 2、保存之前的一份数据镜像 BeanUtils.copyProperties(afterStore, beforeStore); // 3、扣库存 afterStore.setStoreNum(afterStore.getStoreNum() - num); try{ // 4、更新库存 storeDao.update(afterStore); Order order = new Order(); // 一系列order.set...(); // 5、订单保存 orderDao.save(order); }catch(Exception ex){ // 更新库存或者或者订单保存发生异常,手动回滚 storeDao.update(beforeStore); } 复制代码
try { numColors = f.get(1L, TimeUnit.SECONDS) } catch(TimeoutException | ExecutionException ignored) { // User default: minimal coloring is desirable, not required } 复制代码
这一条主要建议在捕获异常之后不要忽略相关的恢复或处理。
现在在代码层面,有一些业务逻辑是有捕获异常,然后进行相应的恢复或处理。但有一些只是打印异常的相关日志,并没有进行相应的恢复或处理,例如我们调用远端服务请求失败后,建议我们还是按照忽略异常的做法写上相应的注释。
try { ResponseEntity<ShareRemoteView> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, ShareRemoteView.class); return responseEntity.getBody(); } catch (Exception ignored) { // 注释说明不处理的原因 LOGGER.error("createShare error.", ignored); return null; } 复制代码
Effective Java异常这一章的内容,对我们写业务代码及业务流程的异常抛出和捕获是有一定指示和帮助的,指导我们写好异常发生条件说明、利用底层异常帮助调试。
但如果我们写的是一些公共组件,我想这一章的帮助会更大,因为这里的每一条都对组件的可读性、可用性、健壮性都有要求。