Optional

Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

常用方法:

Optional.of(T t) : 创建一个 Optional 实例。

Optional.empty() : 创建一个空的 Optional 实例。

Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例。

isPresent() : 判断是否包含值。

orElse(T t) : 如果调用对象包含值,返回该值,否则返回t。

orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值。

map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()。

flatMap(Function mapper):与 map 类似,要求返回值必须是Optional。

下面引用ImportNew的一段内容来告诉我们如何正确使用Optional。比如千万不要写成这样子:

public static String getName(User u) {
Optional<User> user = Optional.ofNullable(u);
if (!user.isPresent())
return "Unknown";
return user.get().name;
}

这样改写非但不简洁,而且其操作还是和第一段代码一样。无非就是用isPresent方法来替代u==null。这样的改写并不是Optional正确的用法,我们再来改写一次。

public static String getName(User u) {
return Optional.ofNullable(u)
.map(user->user.name)
.orElse("Unknown");
}

这样才是正确使用Optional的姿势。那么按照这种思路,我们可以安心的进行链式调用,而不是一层层判断了。看一段代码:

public static String getChampionName(Competition comp) throws IllegalArgumentException {
if (comp != null) {
CompResult result = comp.getResult();
if (result != null) {
User champion = result.getChampion();
if (champion != null) {
return champion.getName();
}
}
}
throw new IllegalArgumentException("The value of param comp isn't available.");
}

由于种种原因(比如:比赛还没有产生冠军、方法的非正常调用、某个方法的实现里埋藏的大礼包等等),我们并不能开心的一路comp.getResult().getChampion().getName()到底。而其他语言比如kotlin,就提供了在语法层面的操作符加持:comp?.getResult()?.getChampion()?.getName()。所以讲道理在Java里我们怎么办!

让我们看看经过Optional加持过后,这些代码会变成什么样子。

public static String getChampionName(Competition comp) throws IllegalArgumentException {
return Optional.ofNullable(comp)
.map(c->c.getResult())
.map(r->r.getChampion())
.map(u->u.getName())
.orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));
}

这就很舒服了。Optional的魅力还不止于此,Optional还有一些神奇的用法,比如Optional可以用来检验参数的合法性。

public void setName(String name) throws IllegalArgumentException {
this.name = Optional.ofNullable(name).filter(User::isNameValid)
.orElseThrow(()->new IllegalArgumentException("Invalid username."));
}

上面代码引用importnew—Java8 如何正确使用 Optional。

接口中的默认方法与静态方法

Java8接口中可以添加静态方法,也可以添加默认方法,默认方法用 default修饰。

public interface Fun<T> {

    default void getName(){
System.out.println("hello world");
} static void getAge(){
System.out.println("nine");
} }

若一个接口中定义了一个默认方法,他的实现类的一个父类定义了具有相同名称和参数列表的方法。则调用该实现类的时候执行父类中的方法。

public class TestF {
public void getName(){
System.out.println("TestF");
}
} public interface TestInterface {
default void getName(){
System.out.println("hello world");
}
} public class Test extends TestF implements TestInterface{
public static void main(String[] args) {
Test t = new Test();
t.getName();//输出的是TestF
}
}

若一个实现类实现了两个接口,如果一个父接口提供一个默认方法,而另一个父接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突,否则会报错。

public interface TestInterface {
default void getName(){
System.err.println("hello world");
}
}
public interface TestInterface1 {
void getName();
}
public class Test1 implements TestInterface, TestInterface1{
public void getName(){
System.out.println("Tes1F");
}
}
java学习群669823128

Java8新特性Optional、接口中的默认方法与静态方法的更多相关文章

  1. 【Java8新特性】接口中的默认方法和静态方法,你都掌握了吗?

    写在前面 在Java8之前的版本中,接口中只能声明常量和抽象方法,接口的实现类中必须实现接口中所有的抽象方法.而在Java8中,接口中可以声明默认方法和静态方法,本文,我们就一起探讨下接口中的默认方法 ...

  2. Java8新特性_接口中的默认方法

    默认方法由来猜想 1. Collection接口.Collections公共类.  同是操作集合,为啥要搞俩?没必要.在接口中搞一些默认实现,一个接口即搞定了. 2. Java8支持Lambda表达式 ...

  3. Java 8 接口中的默认方法与静态方法

    Java 8 接口中的默认方法与静态方法 1. 接口中的默认方法 允许接口中包含具有具体实现的方法,该方法称"默认方法",默认方法使用用 default 关键字修饰. public ...

  4. JDK8.0接口中的默认方法和静态方法

    我们在接口中通常定义的方法是抽象方法,即没有方法体,只有返回值类型和方法名:(public abstract) void Method(); 类在实现接口的时候必须重写抽象方法才可以 jdk8中新加的 ...

  5. 【Java8新特性】- 接口中默认方法修饰为普通方法

    Java8新特性 - 接口中默认方法修饰为普通方法 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学 ...

  6. Java8新特性(一)_interface中的static方法和default方法

    什么要单独写个Java8新特性,一个原因是我目前所在的公司用的是jdk8,并且框架中用了大量的Java8的新特性,如上篇文章写到的stream方法进行过滤map集合.stream方法就是接口Colle ...

  7. java8新特性:interface中的static方法和default方法

    java8中接口有两个新特性,一个是静态方法,一个是默认方法. static方法 java8中为接口新增了一项功能:定义一个或者多个静态方法. 定义用法和普通的static方法一样: public i ...

  8. Java8接口中的默认方法

    Java8新增特性,可以为接口中添加默认方法,实现这个接口的所有类都会继承这个方法,这样看起来,接口和类的界限就有点不明显了,同时也会带来多继承,菱形问题.这样设计的初衷是什么? 重所周知,java8 ...

  9. java8新特性:接口的默认方法与静态方法

    接口中一共可以定义三种方法: 1.抽象方法,也就是需要实现者必须实现的方法,最常见的那种 2.默认方法,不需要实现者实现 3.静态方法,不需要实现者实现 默认方法: 允许在已有的接口中添加新方法,而同 ...

随机推荐

  1. 详解HTTP中GET与POST的区别,不是你看过的标准答案!

    防吐槽声明:本文适合程序员新人,自认阅文无数.技术超叼的大神不用看. GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含 ...

  2. oracle 建立新的表空间

    创建数据表空间 注意粗斜体部分 create tablespace 表空间名称logging datafile 'D:\app\Administrator\oradata\orcl\XXXX.dbf' ...

  3. vscode 编写c++

    参考了 配置文件之前的操作:https://www.cnblogs.com/lianshuiwuyi/p/8094388.html 配置文件具体内容:https://blog.csdn.net/qq5 ...

  4. python之路 JavaScript基础

    一.JavaScript简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为 浏览器的一部分,广泛用于客户端 ...

  5. javascript Date对象 之 设置时间

    之前对js的date对象总是感觉熟悉,而不愿细细深究其所以然,所以每当自己真正应用起来的时候,总会糊里糊涂的,今日花费2个小时的时间仔细钻研了一下,感觉 豁然开朗,故,以此记录,一来 供以后查阅,二来 ...

  6. Python3:Django根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete'

    Python3:Django根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete' 一.分析 在 ...

  7. Stalstack 连接管理配置

    Stalstack 连接管理配置 注:master端,minion端,配置完成.   Saltstack master 测试管理端minion链接状态. salt-key Accepted Keys: ...

  8. 服务端Job调度程序

    GIT地址:https://github.com/youbl/PlanServer

  9. systemverilog中module与program的区别

    我们知道,verilog语法标准中是没有program的,program是systemverilog语法标准新增的内容. 那么,为什么要新增一个program呢?主要考量是基于电路的竞争与冒险. 为避 ...

  10. 什么是MSB/LSB码?

    MSB是Most Significant Bit的缩写,最高有效位.在二进制数中,MSB是最高加权位.与十进制数字中最左边的一位类似.通常,MSB位于二进制数的最左侧,LSB位于二进制数的最右侧. L ...