• 1、Lambda表达式

    Spring代码库使用了大量的函数式接口,使用Java 8,我们可以使用lambda表达式编写更干净、更紧凑的代码。每当期望函数式接口的对象时,我们就可以供给lambda表达式。让我们在讲下一个内容之前先了解函数式接口。

    函数式接口

    具有单个抽象方法的接口可以被称为函数式接口。这里有一些JDK函数式接口的例子:

    Spring4支持Java8的哪些新功能?

    比较程序是函数式的,因为它只有一个抽象非Object方法。虽然它声明了两个抽象方法,’equals’是对应Object中public的方法,因此从计数中排除。具有Object类方法而没有非Object方法的接口不是函数式接口。

    Spring4支持Java8的哪些新功能?

    如果接口具有抽象的非对象类方法并扩展了一个只有对象类方法的非函数式接口,则该接口是函数式的。

    Spring4支持Java8的哪些新功能?

    Spring框架函数式接口的示例:

    Spring4支持Java8的哪些新功能?
    Spring4支持Java8的哪些新功能?

    FunctionalInterface注释可以在接口声明的顶部使用,但它不是强制的。编译器使用此注释来检测接口是否是有效的函数式接口。如果我们尝试定义不止单个的抽象方法到接口,那么编译器会抛出错误。

    Spring4支持Java8的哪些新功能?
    Spring4支持Java8的哪些新功能?

    函数描述符

    接口的函数描述符是接口单个抽象方法的方法类型。方法类型包括参数类型,返回类型和throws子句。

    例子:

    Spring4支持Java8的哪些新功能?

    如何编写Lambda表达式

    Lambda表达式语法可以分为三部分:

    箭头( – >)

    参数列表:

    lambda表达式可以包含零个或多个参数,例如:

    () → { System.out.println(“ No arguments”); }

    (String arg) → { System.out.println(“ One argument : ”+arg); }

    (String arg1, Integer arg2) → { System.out.println(“Two arguments : ”+arg1+” and ”+arg2); }

    表达式主体:

    可以是单个表达式或代码块。单个表达式将被简单地求值和返回。

    例如:(String arg) → { System.out.println(“ One argument : ”+arg); }

    如果主体有语句块,那么它将被评估为方法体,并且隐藏的返回语句将在块执行后将控制返回给调用者。

    现在让我们来看看如何使用lambda表达式:

    例1:

    Spring4支持Java8的哪些新功能?

    //使用lambda表达式

    Spring4支持Java8的哪些新功能?

    例2:

    Spring4支持Java8的哪些新功能?

    //使用lambda表达式

    Spring4支持Java8的哪些新功能?

    你可以通过Spring的回调函数使用lambda表达式。例如,使用ConnectionCallback检索给定JDBC连接的目录可以写为:

    Spring4支持Java8的哪些新功能?

    2、方法引用

    函数式接口也可以使用参考方法或构造器而不调用它们的方法引用来实现。方法引用和lambda表达式是类似的,但方法引用指的是现有类的方法,而lambda定义了一个匿名方法,并将它们作为函数式接口的实例。

    在Java 8中添加了一个新的包,包含通常用于lambda表达式和方法引用的函数式接口:java.util.function。

    3、Date Time API

    Java中现有的日期和时间类有若干问题。Date和Calendar类最大的问题之一是它们不是线程安全的。开发人员不得不在处理日期处理代码时小心并发问题。Date类也不支持国际化,因此不支持时区。开发人员必须编写大量代码来支持各种时区。

    Date和Time类也凸显了API设计的差劲。java.util.Date中的月份以0开头,日期以1开头,年份以1900开头。没有统一性。这些和其他若干Date和Time类中的问题通过Java 8 中Date and Time API得到解决。

    java.time包下新的Date and Time API中,重要的类是LocalDate,LocalTime和ZonedDateTime。

    LocalDate和LocalTime

    LocalDate表示不带时间,默认格式为yyyy-MM-dd的Date。它是一个不可变的类。我们可以使用now()方法获取当前日期。

    创建新的LocalDate实例的例子:

    //获取当前日期

    Spring4支持Java8的哪些新功能?

    我们还可以传递年月日的输入参数来创建LocalDate实例。

    // 2016-04-01

    Spring4支持Java8的哪些新功能?

    LocalTime代表不可变的,不带日期的时间。时间的默认格式为hh:mm:ss.zzz。

    创建新的LocalTime实例的例子:

    //获取当前时间

    Spring4支持Java8的哪些新功能?

    // 18:30:30

    Spring4支持Java8的哪些新功能?

    默认情况下,LocalDate和LocalTime类在默认时区中使用系统时钟。这些类还通过重载的now()方法提供对时区的支持。我们可以传递ZoneId在特定时区获取日期。

    例子:

    //加尔各答(印度)的当前日期

    Spring4支持Java8的哪些新功能?

    另外,还有一个类,LocalDateTime ,它将日期和时间以默认格式yyyy-MM-ddTHH:mm:ss.zzz组合起来。

    //当前日期和时间

    Spring4支持Java8的哪些新功能?

    // 2016-04-01 13:30

    Spring4支持Java8的哪些新功能?

    ZonedDate Time

    这是一个不可变的类,表示日期和时间,包括时区信息。我们可以使用这个类的实例来表示特定事件,如世界的某些地方的会议。

    //使用系统时间和默认区域的当前时间

    Spring4支持Java8的哪些新功能?

    //使用特定时区系统时钟的当前时间

    Spring4支持Java8的哪些新功能?

    Spring 4提供了一个转换框架,支持作为Java 8 Date and Time API一部分的所有类。Spring 4可以采用格式为2016-09-10的字符串,并将其转换为Java 8 LocalDate的实例。Spring 4还支持格式化Java 8日期时间字段,用@DateTimeFormat注释。@DateTimeFormat声明字段应该格式化为日期时间。

    Spring4支持Java8的哪些新功能?

    4、重复注释

    在Java 8之前,不允许将相同类型的多个注释附加到声明或类型(例如类或方法)。作为解决方法,开发人员必须将它们组合到单个容器注释中。

    举例:

    Spring4支持Java8的哪些新功能?

    重复注释允许我们重写相同的代码,而不显式地使用容器注释。虽然此处未使用容器注释,但Java编译器负责将两个注释包装到容器中:

    举例:

    Spring4支持Java8的哪些新功能?

    定义重复注释

    要定义重复注释,标记可以使用@Repeatable重复的注释,并创建一个属性是重复注释类型的数组的注释。

    步骤1:声明可重复注释类型:

    Spring4支持Java8的哪些新功能?

    步骤2:声明容器注释类型。

    Spring4支持Java8的哪些新功能?

    完全实现如下:

    Spring4支持Java8的哪些新功能?

    要在运行时获取注释信息,用@Retention(RetentionPolicy.RUNTIME)注释Roles。

    检索注释

    getAnnotationsByType()或getDeclaredAnnotationsByType()是用于访问注释的Reflection API中的新方法。

    注释也可以使用getAnnotation()或getDeclaredAnnotation()通过容器注释来访问。

    5、结论

    Spring 4仍然使用Java 6和Java 7运行。由于Spring使用了大量的函数式接口,使用Java 8和Spring 4,你将能够使用lambda表达式——拥有函数式接口,并且可以编写更干净和紧凑的代码。