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

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

Null是什么

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

1

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

复制代码
1
String str = (String) null;

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

2

null的instanceof操作返回false

复制代码
1
2
String str = null; System.out.println(str instanceof String);

3

在java中null==null返回true

避免NPE

1.1equals方法

复制代码
1
2
3
4
5
6
7
8
9
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

复制代码
1
2
3
4
5
6
7
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

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

1.4拆箱与解包

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

复制代码
1
2
3
4
5
6
7
8
9
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值实例

复制代码
1
2
Optional<String> name = Optional.of("wenruo"); Optional<String> nullableName = Optional.ofNullable(null);

2.2取数据

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

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

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

复制代码
1
2
//实例有值的情况下 name.ifPresent(value -> System.out.println(value));

2.3在无值情况下指定值

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

复制代码
1
2
3
4
5
System.out.println(nullableName.orElse("* empty *")); System.out.println(nullableName.orElseGet(() -> { int i = 5; return "default value"; }));

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

自定义异常

复制代码
1
2
3
4
5
6
7
8
private class ValueAbsentException extends Throwable { public ValueAbsentException() { super(); } public ValueAbsentException(String message) { super(message); } }

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

复制代码
1
2
3
4
5
6
try { nullableName.orElseThrow(ValueAbsentException::new); } catch (ValueAbsentException e) { e.printStackTrace(); System.out.println("exception caught"); }

3.Optional扩展

3.1map

Optional还有其他的常用操作

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

3.2flatMap

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

3.3filter

复制代码
1
2
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内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部