【小家java】java8新特性之 您所在的位置:网站首页 preparedstatement空指针异常 【小家java】java8新特性之

【小家java】java8新特性之

2023-03-31 22:50| 来源: 网络整理| 查看: 265

相关阅读

【小家java】java5新特性(简述十大新特性) 重要一跃 【小家java】java6新特性(简述十大新特性) 鸡肋升级 【小家java】java7新特性(简述八大新特性) 不温不火 【小家java】java8新特性(简述十大新特性) 饱受赞誉 【小家java】java9新特性(简述十大新特性) 褒贬不一 【小家java】java10新特性(简述十大新特性) 小步迭代 【小家java】java11新特性(简述八大新特性) 首个重磅LTS版本

【小家java】java8新特性之—Base64加密和解密原理 【小家java】java8新特性之—反射获取方法参数名 【小家java】java8新特性之—全新的日期、时间API(完全实现了JSR 310规范) 【小家java】java8新特性之—Optional的使用,避免空指针,代替三目运算符 【小家java】java8新特性之—lambda表达式的的原理 【小家java】java8新特性之—函数式接口(Supplier、Consumer、Predicate、Function、UnaryOperator,通往高阶设计的好工具) 【小家java】java8新特性之—方法引用 【小家java】java8新特性之—Stream API 详解 (Map-reduce、Collectors收集器、并行流) 【小家java】java8新特性之—外部迭代和内部迭代(对比性能差异)

每篇一句

涂磊:嘴不饶人心地善,心不饶人嘴上甜。心善之人能直言,嘴甜之人藏迷奸。宁交一个抬杠的鬼,也不交一个嘴甜的贼

空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分。Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,使得我们就不用显式进行空值检测

创建一个Optional

Optional.of()或者Optional.ofNullable():创建Optional对象,差别在于of不允许参数是null,而ofNullable则无限制。

// 参数不能是null Optional optional1 = Optional.of(10); // 参数可以是非null Optional optional2 = Optional.ofNullable(20); // 参数可以是null Optional optional3 = Optional.ofNullable(null); System.out.println(optional1); //Optional[10] System.out.println(optional2); //Optional[20] System.out.println(optional3); //Optional.empty

如上,我们直接输出了对象。但其实我们用容器装着,调用它的get方法来获取值。所以我们这么做:

System.out.println(optional1.get()); //10 System.out.println(optional2.get()); //20 System.out.println(optional3.get()); //java.util.NoSuchElementException: No value present

我们可以看到,第三句话抛出异常了。这是很多初学者非常容易犯的一个错误,如果里面装的是null值,是不能直接使用get方法的。正确的使用姿势:

if (optional3.isPresent()) { System.out.println(optional3.get()); } 特殊对象:Optional.empty() 所有null包装成的Optional对象public static void main(String[] args) { Optional optional1 = Optional.ofNullable(null); Optional optional2 = Optional.ofNullable(null); System.out.println(optional1 == optional2);// true System.out.println(optional1 == Optional.empty());// true //哪怕泛型类型都不一样 都是true Object o1 = Optional.empty(); Object o2 = Optional.empty(); System.out.println(o1 == o2);// true }

从上面我们可以看出来,里面装null,不管泛型是啥,都是true。所以我们推测,它源码内部肯定维护着一个单例,源码:

private static final Optional EMPTY = new Optional(); public static Optional empty() { Optional t = (Optional) EMPTY; return t; }

看源码里,证实了我们的猜测,没毛病。

isPresent():如果里面有值,返回true,否则返回false

需要注意,empty的就是false。所以一旦get就报错

public static void main(String[] args) { System.out.println(Optional.ofNullable(null).isPresent()); //false System.out.println(Optional.ofNullable(1).isPresent()); //true System.out.println(Optional.empty().isPresent()); false System.out.println(Optional.empty().get()); //java.util.NoSuchElementException: No value present } ifPresent(Consumer consumer):如果option对象保存的值不是null,则调用consumer对象,否则不调用Optional optional1 = Optional.ofNullable(1); // 如果不是null,调用Consumer optional1.ifPresent(new Consumer() { @Override public void accept(Integer t) { System.out.println("value is " + t); } orElse(value):如果optional对象保存的值不是null,则返回原来的值,否则返回value。orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个生产者

本人特意把这两个拿出来放在一起,是因为其实很多人并不知道这两个到底有什么区别呢?下面我就具体来说说他们的区别(完全可以当作面试题,深度啊):

public static void main(String[] args) { Optional.ofNullable(null).orElse(get("a")); Optional.ofNullable(null).orElseGet(() -> get("b")); } private static String get(String s) { System.out.println(s + ":~~我执行了~~"); return s; } 输出: a:~~我执行了~~ b:~~我执行了~~

再看下面这个例子:

Optional.ofNullable("fill").orElse(get("a")); Optional.ofNullable("fill").orElseGet(() -> get("b")); 输出: a:~~我执行了~~ (这里没有输出哦)

对比两者,我们终于发现区别了吧:如果Optional里面的值为null,那两者的效果一模一样。但是当里面的值为null时,我们发现orElse里面代码还是执行的,但是orElseGet里面就不会执行啦。所以使用起来是不是逼格高一点

orElseThrow(判空等场景特别有用)

如下代码,一句话搞定

Date startTime = new Date(Optional.of(req.getFromTime()) .orElseThrow(() -> new MessagePopException("开始时间不能为空")));

如果不用这个我们得这么写

if(req.getFromTime() == null){ throw new MessagePopException("开始时间不能为空"); } Date startTime = req.getFromTime();

稍微麻烦点。使用orElseThrow显得更加的优雅

map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)flatMap():功能与map()相似 具体区别请参考streamAPI那一章最后

Optional还有一个作用,三目运算符,可以代替三目运算符从而支持方法连缀。

System.out.println(Optional.ofNullable("demo").orElse("a")); //demo System.out.println(Optional.ofNullable(null).orElse("a")); //a //或者 使用supplier生产 System.out.println(Optional.ofNullable(null).orElseGet(() -> "abc")); //abc

下面使用的例子,还可以使用map映射:

public static void main(String[] args) { //此处会直接抛出空指针异常 //Optional s = Optional.of(null); //java.lang.NullPointerException //s可以直接使用,是empty,但是不能get,请配合isPresent()使用 //Optional s = Optional.ofNullable(null); //System.out.println(s); //Optional.empty //System.out.println(s.get()); //java.util.NoSuchElementException: No value present //对它进行map操作,我们发现即使为null,我们map方法的x.toString()并没有报错 可谓非常友好 //Optional s = Optional.ofNullable(null).map(x -> x.toString()); //System.out.println(s); //Optional.empty //System.out.println(s.get()); //java.util.NoSuchElementException: No value present 综上,我们可以经常这么来使用,可以很好的达到方法连缀的效果 //1、非常简单的三目运算符 如果是null,就返回1 否则返回里面的值 Integer v = Optional.ofNullable(null).orElse(1); System.out.println(v); //1 //2、三目运算符 结合map 可以实现类型的转换 非常安全且强大 Integer vvv = Optional.ofNullable(null).map(x -> Integer.valueOf(x)).orElse(100); System.out.println(vvv); //100 } 关注A哥AuthorA哥(YourBatman)个人站点[email protected]微 信fsx641385712活跃平台 公众号BAT的乌托邦(ID:BAT-utopia)知识星球BAT的乌托邦每日文章推荐每日文章推荐

BAT的乌托邦



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有