java8特性详解。附使用demo

作者: 唯有努力不欺人丶 | 来源:发表于2019-11-18 17:40 被阅读0次

    首先说起java8“新特性”,我还是有点小迷茫的。
    摸着良心说,在现在这个java11都普遍并且13都问世来袭的情况下,java8新特性这个词本来就挺讽刺的。
    但是!第一份工作,一次偶然接触lambda惊为天人并且兴奋使用。然后被领导一顿狠批的历史却让我一直对“新”技术心有余悸。不得不承认,有些公司有了一套成型的老技术以后确实是轻易不愿意改动(绝对没有抨击的意思!!我十分感谢第一家公司对我的培育)。但是也因为这件事,我一直用着8之前的技术来工作,以后的日子倒是尽量去了解过8,不过一到了代码的编写,又情不自禁的打出了熟悉的语法结构。虽然我会用lambda,但是还是习惯用for新循环。虽然知道了 :: 关键字来传递方法或者构造函数引用,但是还是习惯性get/set来获取属性。
    并且人的记忆在长时间不用的情况下也会慢慢淡忘,说真的,java8看了无数遍,但是现在具体的语法因为没怎么用过,还要想用的时候去网上查一查确定一下是否正确使用。另外吐个槽。java8对于调试真的贼不友善!!!
    咳咳,说跑题了,这次笔者是下定决定,在13来临之际,这个8一定要攻克!起码我要对得起我这个jdk1.8的版本!
    以下是整理的java8的特性,还有一些使用时的demo。

    1、接口的扩展方法

    有一个以前的常识,接口中的方法都是抽象的,但是在java8中这一常识已经被打破了。
    其实现在我们的接口中是可以有完整方法的,实现类实现接口后,这个方法也可以在子类直接使用,这个特性就叫做的扩展方法。
    不过这样的方法需要特别说明的:也就是关键字default

    接口
    实现类
    由上图可见,其实这个接口中的扩展方法就是一个默认的方法。并在在正常的一键生成抽象方法的时候,这个扩展方法也不会被生成(不过可以手动添加此方法类似重载?)

    2、lambda表达式

    这是一个标志性的特性,甚至很早以前我理解的java8就是lambda。不过现在随着越来越接触,知道lambda其实也不过是一个语法。

    Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个函数式接口。下面这个例子就是使用Lambda语法来代替匿名的内部类,代码不仅简洁,而且还可读。
    来自《百度百科》

    其实你让我具体的说,lambda能干什么,我也一句两句说不清,但是都什么能用lambda,我还是可以简单举举例子。
    在代码中,lambda一般写作"->”
    最最常见的遍历,排序,代替匿名内部类。
    下面是几个简单的demo:


    排序

    如果没有lambda,想要从大到小排序就要这么写(默认是从小到大)。其实也说不上特别特别麻烦,但是三四行代码还是少不了的。
    但是如果用了lambda:


    lambda表达式
    对的,短短这么一行代码,就实现了上文三四行的代码的功能!
    其实这里这个lambda是最终版的,中间也经历了一系列的变化。主要能变化的原因基于两点:
    初始版:
            Collections.sort(list, (Integer a, Integer b) -> {
                return b.compareTo(a);
            });
    
    • 对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字

    进化版:

    Collections.sort(list,(Integer a,Integer b) ->b.compareTo(a));
    
    • Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。

    然后最上面我的写法就是最终版了。
    注:这里要说一个小点:在lambda代码行没有完全写完的时候会报错,但是这个不是代码的问题,最开始我学习的时候照着敲敲到一般飘红线,一直怀疑自己写错什么了,后来发现这个机制就是这样的(eclipse编译器,我不知道和编译器有没有关系。然后代码提示也没了,很容易让人怀疑人生的)

    3、函数式接口@FunctionalInterface

    这个其实就是一个注解,表示这个接口只有一个要实现的方法。
    “函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为 默认方法 不算抽象方法,所以你也可以给你的函数式接口添加默认方法。
    我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。(如果没有这个注解也可以的,只不过我觉得这个注解更多是约束写接口的人要注意)


    函数式接口

    看上图,因为我用了这个注解,还写了两个抽象方法,所以报错了。而下图因为只有一个抽象方法,哪怕还有一个默认方法也无所谓。


    函数式接口

    4、方法与构造函数引用

    这个又是一个看起来高大上,实际上也就那样的一个特性(反正我以前不懂的时候感觉这么写贼屌,但是现在用习惯了也就那样)
    其实这个分的很复杂,比如分为方法引用和构造函数引用。构造函数还好一点,大概就是参数的区别。
    但是方法引用又分为实例对象::实例方法引用,类:静态方法引用,类:实例方法引用。
    我这么说可能感觉很模糊,下面是我看到的说的比较详细的一个关于方法与构造函数引用的帖子:
    java8新特性(方法引用、构造器引用)
    我也是看了这边文章,才整体有了大致的概念和细节的划分。这是网址是存在我U盘的,算是启蒙文章吧,表白作者,真的很厉害。
    好了,继续往下说,因为我刚刚已经把原链接贴出去了,所以这里就是简单按照我的理解写几个小demo,顺便说一下,java.util.function 它包含了很多类,用来支持 Java的 函数式编程,我们用方法引用,构造器引用获得的对象是要经过java.util.function的类的包装的。

    demo截图
    然后关于这个接收类,我图中只用了Supplier,如果你需求不同,要换不同的接收类。一共java.util.function提供了四十多种接收类,我也就不一一讲出了,下面是菜鸟教程中对所有函数式接口的整理:
    Java 8 函数式接口
    然后我再截个图附上,懒得跳转的可以直接这么看看:
    函数式接口一
    函数式接口二
    函数式接口三
    函数式接口四
    这里说个题外话,一共函数接口43个,说实话我感觉工作中每个都用过是个很理想的情况,这里简单说一下我个人的学习使用方法:
    我都是先根据实际业务需求,差不多计划好这次要用哪种接口,然后再去菜鸟教程中的接口中去一个个查找,感觉某个恰似是我想要的,然后在demo里先尝试简单的使用,使用完成后才会放到真正的业务代码里。
    我觉得说43中完全熟记于心有点点不太现实,而且真的有的我至今没用过,甚至没接触过,就这这种随着学随着用我也记住了好几种的用法,多用几次就做到随手拿来就用。
    顺便附上我觉得这一块写的不错的一个帖子:
    JAVA8十大新特性详解(精编)

    5、Optional 类

    这个类其实东西很简单,用起来也很顺手(我在接触java8之前先在jpa里看到过这个类,当时还很蠢的以为这个类是jpa研发的)。

    Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

    Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。

    Optional 类的引入很好的解决空指针异常

    上面三句话我觉得把这个类讲的很清楚,其实就是一个预防空指针的类。


    Optional类的方法一
    Optional类的方法二

    6、日期时间 API

    这个怎么说呢,java8推出了新的时间日期API,不过我早整理过了,这里直接甩链接,有兴趣的用到的可以去看看。
    java中时间日期格式讲解和转换方法

    然后关于新特性这块,就到这吧,其实说的东一块西一块的,可能排版也很乱,莫名其妙乱七八糟的,不过我真的尽力了。。
    因为这里的东西很多,说浅了也不容易让人懂,说深了一块内容就能无限延伸下去。这个记录也算是这几天的整理笔记,如果想自己了解的亲们,建议还是看完整的教材。
    如果稍稍帮到你了麻烦点个喜欢点个关注,也祝大家工作顺顺利利!

    相关文章

      网友评论

        本文标题:java8特性详解。附使用demo

        本文链接:https://www.haomeiwen.com/subject/rbrwbctx.html