我是靠谱客的博主 生动指甲油,最近开发中收集的这篇文章主要介绍避免NPENull是什么避免NPE2.Optional3.Optional扩展,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在java开发中中NPE异常是常见异常,在阿里java开发手册中就明确强调防止NPE是调用者的责任是程序员基本修养,本篇博客先讲解NUll的知识点,随后讲解利用一些小技巧避免NPE

Null是什么

null是java中的关键字用来表示一些缺失的东西,null是所有引用类型的默认值,在这一部分强调几个关于null的知识点

1

null既不是对象也不是一种类型,它是一种特殊的值,你可以将null赋值任何引用类型,也可以将null强制转化为任何引用类型
如下

String str = (String) null;

强制转化过程编译器并不会报错

2

null的instanceof操作返回false

String str = null;
System.out.println(str instanceof String);

3

在java中null==null返回true

避免NPE

1.1equals方法

public void equals() {
//代表未知的对象,可能会是NULL也可能不是NULL
Object unKnowObject = null;
//这样某些情况下可能会抛出NULLPointException
System.out.println(unKnowObject.equals("str"));
//改成如下
//str一定不会空,所以不会抛出异常
System.out.println("str".equals(unKnowObject));
}

1.2valueOf与toString

利用String.valueOf避免NPE

public void toMyString() {
BigDecimal bigDecimal = null;
//避免如下写法,当对象为空时候会抛出异常
System.out.println(bigDecimal.toString());
//使用String静态方法
System.out.println(String.valueOf(bigDecimal));
}

1.3元素的list避免null

从数据库中检索数据如果结果集为空,利用0元素的list或者set来避免返回null

public void retrieveDataFromDB() {
//如果没有检索到数据,返回0元素的list,map,set而不是null
List result = Collections.EMPTY_LIST;
}

1.4拆箱与解包

下面这个例子是我们统计一个数字数组每个数字出现的次数
如下的写法是常见错误

public void unBox() {
int[] array = {20, 5, 7, 5, 9, 2};
final Map<Integer, Integer> numCount = new HashMap<>();
for (int v : array) {
int result = numCount.get(v);
numCount.put(v, ++result);
}
numCount.entrySet().stream().forEach(entry -> System.out.println(entry.getKey() + " -> " + entry.getValue()));
}

int result=numCount.get(v)取出的数据可能是null,而result是基本类型,对null进行拆箱自然就抛NPE异常了,所以get时需要进一步判断值是否是null

除了上面几种方法之外,我们还可以使用guava或者java8的Optional来避免NPE,下面主要讲解jdk中Optional使用

2.Optional

2.1初始化

初始化Optional有两种方法
1. of: of函数传入的参数不允许为null,否则抛出NullPointerException
2. ofNullable: ofNullable允许参数为空,创建一个不包含任何值得Optional值实例

Optional<String> name = Optional.of("wenruo");
Optional<String> nullableName = Optional.ofNullable(null);

2.2取数据

取数据时可以先isPresient判断是否有具体的数据,然后再get,不过get时候如果Optional没有数据就会抛异常

//isPresent函数有具体值得情况下返回true
if (name.isPresent()) {
System.out.println(name.get());
}
//如果对空类型调用get会抛出异常
System.out.println(nullableName.get());

或者利用lambda表达式在实例有值的时候进行操作

//实例有值的情况下
name.ifPresent(value -> System.out.println(value));

2.3在无值情况下指定值

orElse和orElseGet可以在无值的情况下指定值,orElse可以无值的情况下指定字符串默认值
而orElseGet可以利用Supplier接口生成默认值

System.out.println(nullableName.orElse("* empty *"));
System.out.println(nullableName.orElseGet(() -> {
int i = 5;
return "default value";
}));

2.4值不存在的情况下抛自定义异常

自定义异常

private class ValueAbsentException extends Throwable {
public ValueAbsentException() {
super();
}
public ValueAbsentException(String message) {
super(message);
}
}

自定义在值不存在的情况下抛出指定异常

try {
nullableName.orElseThrow(ValueAbsentException::new);
} catch (ValueAbsentException e) {
e.printStackTrace();
System.out.println("exception caught");
}

3.Optional扩展

3.1map

Optional还有其他的常用操作

//map可以返回任意类型
Optional<String> upperName = name.map(value -> value.toUpperCase());
System.out.println(upperName.orElse("no value found"));

3.2flatMap

//flatMap返回值必须是Optional类型
name = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(name.orElse("No Value Found"));

3.3filter

Optional<String> longName = name.filter(value -> value.length() > 10);
System.out.println(longName.orElse("the string length less than 10"));

最后

以上就是生动指甲油为你收集整理的避免NPENull是什么避免NPE2.Optional3.Optional扩展的全部内容,希望文章能够帮你解决避免NPENull是什么避免NPE2.Optional3.Optional扩展所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部