前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >写给小胖看的 Java 集合处理、异常处理、空值处理!

写给小胖看的 Java 集合处理、异常处理、空值处理!

作者头像
JavaFish
发布2021-01-05 10:47:18
7390
发布2021-01-05 10:47:18
举报
文章被收录于专栏:狗哥的 Java 世界

优质文章,及时送达

巨人的肩膀:https://llchen60.com/Java - 集合处理 - 和 - 空值处理 /

Arrays.asList

业务开发当中,我们常常会将原始的数组转换为 List 类数据结构,来继续展开各种 Stream 操作

Arrays.asList 无法转换基本类型的数组,可以使用 Arrays.stream 来进行转换

Arrays.asList 返回的 list 是不支持增删操作的,其返回的 List 是 Arrays 的内部类 ArrayList。内部继承自 AbstractList,没有覆写父类的 add 方法

对原始数组的修改会影响到我们获得的那个 List

ArrayList 实际上是使用了原始的数组,因此在使用的时候,最好再使用 New ArrayList 来实现解耦

空值处理

NullPointerException

可能出现的场景

  • 参数值是 Integer 等包装类型,使用时因为自动拆箱出现了空指针异常
  • 字符串比较
  • ConcurrentHashMap 这种容器不支持 Key 和 Value 为 null,强行 put null 的 key 或 Value 会出现空指针异常
  • 方法或远程服务返回的 list 是 null,没做判空就直接调用,出现空指针异常
  • 联级调用的 null check

best practice

  • string.equalsTo(variableName)
  • Optional.ofNullable()
  • orElse()

异常处理

在业务代码层面考虑异常处理

大多数业务应用都采用三层架构

Controller 层

  • 负责数据访问实现,一般没有业务逻辑
  • 根据情况来做忽略,降级,或者转化为一个友好的异常

Service 层

  • 负责核心业务逻辑,包括外部服务调用,访问数据库,缓存处理,消息处理等
  • 一般会涉及到数据库事务,出现异常不适合捕获,否则事务无法自动回滚

Repository 层

  • 负责信息收集,参数校验,转换服务层处理的数据适配前端,轻业务逻辑
  • Controller 捕获异常,然后需要给用户友好用户的提示

框架层面的异常处理

尽量不要在框架层面做异常的自动,统一的处理

框架应当来做兜底工作,如果异常上升到最上层逻辑还是无法处理的话,可以用统一的方式进行异常转换

  • @RestControllerAdvice
  • @ExceptionHandler
不要直接生吞异常

捕获了异常以后不应该生吞,因为吞掉的异常如果没有正常处理的话,出现 Bug 会很难发现。

需要有合适的转化成用户友好的异常,或者至少在 warn, error 级别来做 log

保留原始的信息

在捕捉了异常之后,一定要记得在 log 或者在向外扔出的异常之中记录原始异常信息

代码语言:javascript
复制
catch (IOException e) {
    //只保留了异常消息,栈没有记录
    log.error("文件读取错误, {}", e.getMessage());
    throw new RuntimeException("系统忙请稍后再试");
}


catch (IOException e) {
    throw new RuntimeException("系统忙请稍后再试", e);
}
小心 finally 中的异常 + try with resources

注意在资源释放处理等收尾操作的时候也可能会出现异常,这种时候,如果 try block 逻辑和 finnally 逻辑都有异常抛出的话,try 当中的异常会被 finnally 中的异常覆盖掉,这会让问题变得非常不明显

代码语言:javascript
复制
@GetMapping("wrong")
public void wrong() {
    try {
        log.info("try");
        //异常丢失
        throw new RuntimeException("try");
    } finally {
        log.info("finally");
        throw new RuntimeException("finally");
    }
}

对于实现了 AutoCloseable 接口的资源,可以使用 try-with-resources 来释放资源,就是在 try 中带资源的声明

  • try catch finally vs try with resources
代码语言:javascript
复制
Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}
线程池任务的异常处理
  • 设置自定义的异常处理程序作为保底,比如在声明线程池时自定义线程池的未捕获异常处理程序
代码语言:javascript
复制
new ThreadFactoryBuilder()
  .setNameFormat(prefix+"%d")
  .setUncaughtExceptionHandler((thread, throwable)-> log.error("ThreadPool {} got exception", thread, throwable))
  .get()

Reference

  • https://www.baeldung.com/java-try-with-resources
  • https://time.geekbang.org/column/article/220230
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一个优秀的废人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Arrays.asList
  • 空值处理
    • NullPointerException
    • 异常处理
      • 在业务代码层面考虑异常处理
        • 不要直接生吞异常
          • 保留原始的信息
            • 小心 finally 中的异常 + try with resources
              • 线程池任务的异常处理
              • Reference
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档