首页 欧洲联赛正文
  • 判空灾祸
  • NullObject形式师宗县陈文波
  • .NR Nul羽加立l Object
  • 装置办法
  • Optional
  • Kotlin

判空灾祸

NullPointerException

作为搬砖党的一族们,咱们对判空必定再了解不过了,不要跟我说你很少进行判空,除非你喜爱NullPointerException。

不过NullPointerException关于许多猿们来说,也是Exception宗族中最挨近的一员了。

Wowo

为了防止NullPointerException来找咱们,咱们经常会进行如下操作。

if (data != null) {
do sth.
}

假如一个类中屡次运用某个目标,那你或许要一顿操作,so:

1

“国际第九大奇观”就这样诞生了。Maybe你会想,项目中必定不止你一个人会这样一顿操作,然后按下Command+Shift+F,本相就在眼前:

2

What,咱们有挨近一万行的代码都是在判空?

3

好了,接下来,要进入正题了。

NullObject形式

关于项目中无数次的判空,对代码质量整齐度产生了十分之恶劣的影响,关于这种现象,咱们称之为“判空灾祸”。

那么,这种现象怎样管理呢,你或许听说过NullObject形式,不过这不是咱们今日的兵器,可是仍是需求介绍一下NullObject形式。

什么是NullObject形式呢?

In object-oriented computer programming, a null object is an object with no referenced value or with defined neutral ("null") behavior. The null object design pattern describes the uses of such objects and their behavior (or lack thereof).

以上解析来自Wikipedia。

NullObject形式初次宣布在“ 程序设计形式语言 ”系列丛书中。一般的,在面向目标语言中,对目标的调用前需求运用判空查看,来判别这些目标是否为空,由于在空引证上无法调用所需办法。

空目标形式的一种典型完成办法如下图所示(图片来自网络):

4

示例代码如下(命名来自网络,哈哈到底是有多懒):

Nullable是空目标的相关操作接口,用于确认目标是否为空,由于在空目标形式中,目标为空会被包装成一个Object,成为Null Object,该目标会对原有目标的一切办法进行空完成。。

public interface Nullable {
boolean isNull();
}

这个接口界说了事务目标的行为。

public interface DependencyBase extends Nullable {
void Operation();
}

这是该目标的实在类,完成了事务行为接口DependencyBase与空目标操作接口Nulla姜河娜ble。

public class Dependency implements DependencyBase, Nullable {
@Override
public void Operation() {
System.out.print("Test!");
}
@Override
public boolean isNull() {
return fals看逼e;
}
}

这是空目标,对原有目标的行为进行了空完成。

public class NullObject implements DependencyBase{
@Override
public void Operation() {
// do nothing
}
@Override
public boolean isNull() {
return true;
}
}

在运用时,能够经过工厂调用办法来进行空目标的调用,也能够经过其他如反射的办法对目标进行调用(一般多耗时几毫恩师颂秒)在此不进行详细叙说。

public cl在 Java 中怎样典雅地判空ass Factory {
public static DependencyBase get(Nullable dependencyBase){
if (dependencyBase == null){
return new NullObject();
}
return new Dependency();
}
}

这是一个运用典范,经过这种形式,咱们不再需求进行目标的判空操作,而是能够直接运用目标,也不必忧虑NPE(NullPointerException)的问题。

public class Client {
public void test(DependencyBase dependencyBase){
Factory.get(dependencyBase).Operation();
}
}

关于空目标形式,更详细的内容咱们也能够多找一找材料,上述仅仅对NullObject的简略介绍,可是,今日我要引荐的是一款帮忙判空的插件NR Null Object,让咱们来典雅地进行判空,不再进行一顿操作来界说繁琐的空目标接口与空独享完成类。

.NR Null Object

NR Null Object是一款适馈组词用于Android Studio、IntelliJ IDEA、PhpStorm、WebStorm、PyCharm、RubyMine、AppCode、CLion、GoLand、DataGrip等IDEA的Intellij插件。其能够依据现有目标,快捷快速生成其空目标形式需求的组成成分,其包括功用如下:

  • 剖析所选类可声明为接口的办法;
  • 笼统出公有接口;
  • 创立空目标,自无极金仙异界游动完成公有接口;
  • 对部分函数进行可为空声明;
  • 可追加函数进行再次生成;
  • 主动的函数命名标准
  • 让咱们来看一个运用典范:

5

怎样样,看起来是不是十分快速快捷,只需求在原有需求进行屡次判空的目标中,邮件弹出菜单,挑选Generate,并挑选NR Null Object即可主动生成相应的空目标组件。

那么怎样来取得这款插件呢?

装置办法

能够直接经过IDEA的Preferences中的Plugins库房进行装置。

挑选 P标特火references → Plugins → Browse repositories

6

查找“NR Null Oject”或许“Null Oject”进行含糊查询,点击右侧的Install,restart IDEA即可。

7

Optional

还有一种办法是运用Java8特性中的Optional来进行典雅地判空,Optional来自官方的介绍如下:

A container object which may or may not contain a non-null value. If a value is present, isPresent()will return true and get() will return the value.

一个或许包括也或许不包括非null值的容器目标。 假如存在值,isPresent()将回来true,get()将回来该值。

话不多说,举个比如。

栗子

有如下代码在 Java 中怎样典雅地判空,需求取得Test2中的Info信息,可是参数为Test4,咱们要一层层的请求,每一层都取得的目标都或许是空,最终的代码看起来就像这样。

 public String testSimple(Tes在 Java 中怎样典雅地判空t4 test) {
if (test == null) {
return "";
}
if (test.getTest3() == null) {
return "";
}
if (test.getTest3().getTest2() == null) {
return "";
}
if (test.getTest3().getTest2().getInfo() == null) {
return "";
}
return test.getTes广州今日天气t3().getTest2().getInfo();
}

可是运用Optional后,整个就都不一样了。

 public String testOptional(Test test) {
return Optional.ofNullable(test).flatMap(Test::getTest3)
.flatMap(Test3::getTest2)
.map(Test2::getInfo)
.orElse("");
}

1.Optional.ofNullable(test),假如test为空,则回来一个单例空Optional目标,假如非空则回来一个Optional包装目标,Optional将test包装;

 public static  Optional ofNullable(T value) {
return value == null ? empty() : of(value);
}

2.flatMap(Test::getTest3)判别test是否为空,假如为空,持续回来第一步中的单例Optional目标,不然调用Test的getTest3办法;

 public Optional flatMap(Function> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return emp吴山居事情账ty();
else {
return Objects.requireNonNull(mapper.apply(水咲value));
}
}

3.flatMap(Test3::getTest2)同上调用Test3的getTest2办法;

4.map(Test2::getInfo)同flatMap相似,可是flatMap要求Test3::getTest2回来值为Optional类型,而map不需求,flatMap不会多层包装,在 Java 中怎样典雅地判空map回来会再次包装Optional;

 public Optional map(Function
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}

5.orElse("");取得map中的value,不为空则直接回来value,为空则回来传入的参数作为默许值。

public T orElse(T other) {
return value != null ?在 Java 中怎样典雅地判空 value : other;
}

怎样样,运用Op乌黑英豪的一击无双tional后咱们的代码是不是瞬间变得十分整齐,或许看到这段天天向上20121116代码你会有许多疑问,针对杂乱的一长串判空,Optio在 Java 中怎样典雅地判空nal有它的优势,可是关于简略的判空运用Optional也会添加代码的阅览本钱、编码量以及团队新成员的学习本钱。究竟Optional在现在还并没有像RxJava那样盛行,它还具有必定的局限性。

假如直接运用Java8中的Optional,需求d2671确保安卓API级别在24及以上。

image-20181124085913887.png

你也能够直接引进Google的Guava。(啥是Guava?来自官方的提示)

Guava is a set of core libraries that includes new collection types (such as m陈细妹ultimap and multiset), imm阮初夏霍殊utable collections, a graph library, 在 Java 中怎样典雅地判空functional types, an in-memory cache, and APIs/utilities for concurrency, I/O, hashing, primitives, reflection, string processing, and much more!

引证办法,就像这样:

 dependencies {
compile 'com.google.guava:guava:27.0-jre'
// or, for Android:
api 'com.google.g宋子夫uava:guava:27.0-android'
}

不过IDEA默许会显现黄色,提示让你将Guava表达式迁移到Java Api上。

image-3.png

当然,你也能够经过在Preferences查找"Guava"来Kill掉这个Yellow的提示。

image-4.png

关于Optional运用还有许多技巧,感兴趣能够查阅Guava和Java8相关书本和文档。

运用Optional具有如下长处:

  1. 将防护式编程代学长是匹狼码完美包装
  2. 链式调用
  3. 有用防止程序代码中的空指针

可是也相同具有一些缺陷:

  1. 盛行性不是十分抱负,团队新成员需求学习本钱
  2. 安卓中需求引进Gua五点支撑法忌讳va,需求团队每个人处理IDEA默许提示,或许忍耐黄色提示
  3. 有时候代码阅览看起来或许会如下图所示:

Duang

Kotlin

当然,Kotlin以具有优异的空安全性为一大特征,并能够与Java很好的混合运用,like this:

 test1?.test2?.test3?.test4

假如你现已开始运用了Kotlin,能够不必再写纷乱的防护判空语句。假如你还没有运用Kotlin,并不引荐为了判空典雅而直接转向Kotlin。

来历:http://t.cn/EM8Yeul


查找微信号(ID:芋道源码),能够取得各种 Java 源码解析。

而且,回复【书本】后,能够收取笔者引荐的各种 Java 从入门到架构的书本。

来吧,骚年~

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。