Java8中新特性Optional、接口中默认方法和静态方法详解

 更新时间:2017年12月28日 09:19:14   作者:我不是李大侠  
Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级。下面这篇文章主要给大家介绍了关于Java8中新特性Optional、接口中默认方法和静态方法的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。

前言

毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。

Java 8是Java的一个重大版本,有人认为,虽然这些新特性领Java开发人员十分期待,但同时也需要花不少精力去学习。下面本文就给大家详细介绍了Java8中新特性Optional、接口中默认方法和静态方法的相关内容,话不多说了,来一起看看详细的介绍吧。

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");
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • jmeter接口测试之使用rsa算法加密解密的代码

    jmeter接口测试之使用rsa算法加密解密的代码

    这篇文章主要介绍了jmeter接口测试-使用rsa加密解密算法,部分接口采用了rsa加密算法,我们的jmeter 也是可以直接拿来调用的,不需要开发配合去掉加密代码,需要的朋友可以参考下
    2022-03-03
  • Java代码注释规范详解

    Java代码注释规范详解

    代码附有注释对程序开发者来说非常重要,随着技术的发展,在项目开发过程中,必须要求程序员写好代码注释,这样有利于代码后续的编写和使用。下面给大家分享java代码注释的规范,需要的朋友参考下
    2016-02-02
  • Java微信公众平台之自定义菜单

    Java微信公众平台之自定义菜单

    这篇文章主要为大家详细介绍了Java微信公众平台之自定义菜单,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • 使用FeignClient进行微服务交互方式(微服务接口互相调用)

    使用FeignClient进行微服务交互方式(微服务接口互相调用)

    这篇文章主要介绍了使用FeignClient进行微服务交互方式(微服务接口互相调用),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • IDEA创建parent项目(聚合项目)

    IDEA创建parent项目(聚合项目)

    这篇文章主要介绍了IDEA创建parent项目(聚合项目),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java实现的爬虫抓取图片并保存操作示例

    Java实现的爬虫抓取图片并保存操作示例

    这篇文章主要介绍了Java实现的爬虫抓取图片并保存操作,涉及Java针对页面URL访问、获取、字符串匹配、文件下载等相关操作技巧,需要的朋友可以参考下
    2018-08-08
  • JAVA+Hibernate 无限级分类

    JAVA+Hibernate 无限级分类

    主要看menu_id和parent_id这两个字段。 Eclipse生成的表持久映射:(说明:自己加level属性,作用:为了记录种类所在深度)
    2008-07-07
  • Toolbar制作菜单条过程详解

    Toolbar制作菜单条过程详解

    Toolbar制作菜单条过程详解...
    2006-12-12
  • Java中super和this的用法详解

    Java中super和this的用法详解

    这篇文章主要介绍了Java中super和this的用法详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • springboot内置tomcat之NIO处理流程一览

    springboot内置tomcat之NIO处理流程一览

    这篇文章主要介绍了springboot内置tomcat之NIO处理流程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12

最新评论