出现空指针异常的几种情况
- 调用了空对象的实例方法
- 调用了空对象的属性
- 当数组是一个空对象时,取他的长度
- null当作Throwable的值
- 方法的返回值为null,调用方法直接去使用
如何避免
- 使用前一定初始化,检查是否初始化
- 避免在函数中返回null,加注释
- 外部传值,及时进行判断
自动拆箱引发的空指针问题
- 变量赋值自动拆箱出现的空指针
- 方法传参时自动拆箱出现的空指针
- 用于大小比较的场景
如何避免
- 基本数据类型优于包装器类型,优先考虑基本数据类型
- 对于不确定的包装器类型,要检验是否为null
- 对于值为null的包装器类型,赋值为0
字符串,集合,数组空指针问题
- 字符串使用equals可能会报空指针错误
- 对象数组new之后,但元素没有初始化
- list对象addAll传递null会抛出空指针
Optional<T> (jdk8之后)
- 容器类,代表存在于不存在,可以避免空指针异常,可看作至多包含一个元素的集合,不能作为类的字段使用
- isPresent() 如果optional元素存在,则返回true
- orElse(默认值) 存在即返回,空则提供默认值
- orElseGet(函数) 存在即返回,空则由函数产生
- orElseThrow(异常) 存在即返回,空则抛出括号中的异常
- ifPresent(操作) 存在则进行操作,不存在不进行处理
- map可以对Optional中对象进行操作且返回一个Optional对象,且map方法可以无限级联
//对optional中u对象进行getName方法,返回一个包含String的Optional对象,orELse判断是否为null,不存在提供默认值
optional.map(u->u.getName()).orElse("默认值");
异常处理
- 使用异常,而不是用返回码(字符串或数字返回码)
- 主动捕获检查性异常(try..catch),并对检查信息进行反馈(返回提示异常信息)
- 一个方法中避免使用多个或者嵌套的try catch
- 捕获具体的异常,而不是捕获通用异常
- 合理的设计自定义异常类(明确定义可能出现的异常类型提示)
常见异常
- 并发修改异常concurrentModificationException
- 类型转换异常ClassCastException(1.可以通过getClass().getName()获取对象类名 2.通过instanceof返回Boolean类型判断类是否符合)
- 枚举查找异常(非法参数异常)(1.对非法参数异常进行抓取 2.for对枚举循环判断,但每次查询都遍历,效率低 3.建立静态map索引,只有一次循环枚举的过程 4.使用google Guava Enums,需要相关依赖)
//4.getIfPresent返回Optional类,使用orNull方法,元素不存在返回null
return Enums.getIfPresent(枚举类,type) orNull();
使用try finally资源泄露
- try finally对单个资源基本没有问题
- 同时操作多个资源,代码冗长,存在内存泄漏的风险
- try-with-resources 不仅比try-finally方便,且不易出错 try(资源){对资源的操作} 执行完中括号中操作后自动对()中资源进行关闭,可以在()中使用";"进行管理多个资源