Java8中新特性Optional、接口中默认方法和静态方法详解
前言
毫无疑问,Java8是Java自Java5(发布于2004年)之后的最重要的版本。这个版本包含语言、编译器、库、工具和JVM等方面的十多个新特性。
Java8是Java的一个重大版本,有人认为,虽然这些新特性领Java开发人员十分期待,但同时也需要花不少精力去学习。下面本文就给大家详细介绍了Java8中新特性Optional、接口中默认方法和静态方法的相关内容,话不多说了,来一起看看详细的介绍吧。
Optional
Optional类(java.util.Optional)是一个容器类,代表一个值存在或不存在,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常。
常用方法:
- Optional.of(Tt):创建一个Optional实例。
- Optional.empty():创建一个空的Optional实例。
- Optional.ofNullable(Tt)若t不为null,创建Optional实例,否则创建空实例。
- isPresent():判断是否包含值。
- orElse(Tt):如果调用对象包含值,返回该值,否则返回t。
- orElseGet(Suppliers):如果调用对象包含值,返回该值,否则返回s获取的值。
- map(Functionf) 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
- flatMap(Functionmapper)与map类似,要求返回值必须是Optional。
下面引用ImportNew的一段内容来告诉我们如何正确使用Optional。比如千万不要写成这样子:
publicstaticStringgetName(Useru){
Optionaluser=Optional.ofNullable(u);
if(!user.isPresent())
return"Unknown";
returnuser.get().name;
}
这样改写非但不简洁,而且其操作还是和第一段代码一样。无非就是用isPresent方法来替代u==null。这样的改写并不是Optional正确的用法,我们再来改写一次。
publicstaticStringgetName(Useru){
returnOptional.ofNullable(u)
.map(user->user.name)
.orElse("Unknown");
}
这样才是正确使用Optional的姿势。那么按照这种思路,我们可以安心的进行链式调用,而不是一层层判断了。看一段代码:
publicstaticStringgetChampionName(Competitioncomp)throwsIllegalArgumentException{
if(comp!=null){
CompResultresult=comp.getResult();
if(result!=null){
Userchampion=result.getChampion();
if(champion!=null){
returnchampion.getName();
}
}
}
thrownewIllegalArgumentException("Thevalueofparamcompisn'tavailable.");
}
由于种种原因(比如:比赛还没有产生冠军、方法的非正常调用、某个方法的实现里埋藏的大礼包等等),我们并不能开心的一路comp.getResult().getChampion().getName()到底。而其他语言比如kotlin,就提供了在语法层面的操作符加持:comp?.getResult()?.getChampion()?.getName()所以讲道理在Java里我们怎么办!
让我们看看经过Optional加持过后,这些代码会变成什么样子。
publicstaticStringgetChampionName(Competitioncomp)throwsIllegalArgumentException{
returnOptional.ofNullable(comp)
.map(c->c.getResult())
.map(r->r.getChampion())
.map(u->u.getName())
.orElseThrow(()->newIllegalArgumentException("Thevalueofparamcompisn'tavailable."));
}
这就很舒服了。Optional的魅力还不止于此,Optional还有一些神奇的用法,比如Optional可以用来检验参数的合法性。
publicvoidsetName(Stringname)throwsIllegalArgumentException{
this.name=Optional.ofNullable(name).filter(User::isNameValid)
.orElseThrow(()->newIllegalArgumentException("Invalidusername."));
}
上面代码引用importnew—Java8如何正确使用Optional。
接口中的默认方法与静态方法
Java8接口中可以添加静态方法,也可以添加默认方法,默认方法用default修饰。
publicinterfaceFun{ defaultvoidgetName(){ System.out.println("helloworld"); } staticvoidgetAge(){ System.out.println("nine"); } }
若一个接口中定义了一个默认方法,他的实现类的一个父类定义了具有相同名称和参数列表的方法。则调用该实现类的时候执行父类中的方法。
publicclassTestF{
publicvoidgetName(){
System.out.println("TestF");
}
}
publicinterfaceTestInterface{
defaultvoidgetName(){
System.out.println("helloworld");
}
}
publicclassTestextendsTestFimplementsTestInterface{
publicstaticvoidmain(String[]args){
Testt=newTest();
t.getName();//输出的是TestF
}
}
若一个实现类实现了两个接口,如果一个父接口提供一个默认方法,而另一个父接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突,否则会报错。
publicinterfaceTestInterface{
defaultvoidgetName(){
System.err.println("helloworld");
}
}
publicinterfaceTestInterface1{
voidgetName();
}
publicclassTest1implementsTestInterface,TestInterface1{
publicvoidgetName(){
System.out.println("Tes1F");
}
}
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。