掌握Java 8日期时间API:系统开发必备的Java API与框架使用指南

课程目标包括:了解重要的 Java API,并且要掌握一些必备框架的使用,这些内容在系统开发中是标配,是需要掌握的。

掌握Java 8日期时间API:系统开发必备的Java API与框架使用指南

日期时间API

Java 8 发布了新的 Date-Time API(JSR 310),以此来进一步强化对日期与时间的处理。

- 格式转换不够方便。

Java 8 在 java.time 包中提供了许多新的 API。其中有两个 API 较为重要,分别如下:

新的 java.time 包包含了处理时钟(clock)的操作。

之前的日期时间 API 状况不佳,通常大家都会自行编写 DateTimeUtil 工具类。后来出现了 Joda-Time 开源项目,它确实为广大程序员解决了大问题。(这就是为什么程序员不仅要会使用框架和 Java API,还需要明白其原理。如果底层本身存在缺陷或实现不好,我们最起码要知道,当然我们也可以对其进行增强或自己实现。)

LocalDate 和 LocalTime 类以及 LocalDateTime 类在处理时区并非必须的情况下可以被使用。以下是代码示例:


import java.time.LocalDate;
import java.time.LocalTime;
引入 Java 中的时间类 LocalDateTime;使用 Java 中的时间类 LocalDateTime;导入 Java 里的时间类 LocalDateTime;将 Java 中的时间类 LocalDateTime 进行导入;利用 Java 中的时间类 LocalDateTime;借助 Java 中的时间类 LocalDateTime
import java.time.Month;
 
public class Java8Tester {
公共静态的 void 主函数(字符串数组 args){
创建了一个名为 Java8Tester 的对象 java8tester,其类型为 Java8Tester,通过 new 关键字进行实例化。
java8tester 对本地日期时间进行了测试。
   }
    
该方法的目的是检验本地日期时间的相关功能和特性。
    
      // 获取当前的日期时间
LocalDateTime 现在的时间 = LocalDateTime.now();
System.out 会打印出 "当前时间: " 以及 currentTime 的值。
        
当前时间转换为本地日期,得到的本地日期记为 date1 。
System 输出了 "date1: " 与 date1 进行拼接后的内容。
        
当前时间获取到的月份为 month,这个 month 就是具体的月份数值。
获取当前时间的月份中的日期,将其赋值给变量 day,即 day 等于 currentTime 获取到的月份中的日期。
当前时间的秒数为 currentTime.getSecond() 所获取的值,将其赋值给整数 seconds 。
        
System.out.println("秒数为: " + seconds);
        
LocalDateTime date2;currentTime 的日期设置为 10 号,年份设置为 2012 年,得到 date2。
System 输出了 "date2: " 与 date2 进行拼接后的内容。
        
      // 12 december 2014
LocalDate 是一个日期类,通过调用其 of 方法来创建一个特定日期的对象。这里创建的日期是 2014 年 12 月 12 日,其中月份使用了 Month.DECEMBER 来表示 12 月,然后将年、月、日作为参数传递给 of 方法,最终得到了 date3 这个 LocalDate 对象。
System.out 会打印出 "date3: " 以及 date3 的值。
        
      // 22 小时 15 分钟
LocalTime 被设定为 22 时 15 分。  LocalTime 等于 22 点和 15 分组成的时间。  LocalTime 是由 22 以及 15 构成的时间。  LocalTime 为 22 时 15 分所对应的时间。  LocalTime 被设定成 22 点 15 分的那个时间。
System.out 输出 "date4: " 与 date4 进行拼接后的内容
        
      // 解析字符串
LocalTime 为 date5 ,其值是通过 "20:15:30" 解析得到的。
System.out 会打印出 "date5: " 与 date5 相连的内容
   }
}

如果我们需要考虑到时区,就可以使用时区的日期时间API:


引入 Java 中的时间类 ZonedDateTime ;
import java.time.ZoneId;
 
public class Java8Tester {
   public static void main(String args[]){
      Java8Tester java8tester = new Java8Tester();
java8tester 对 ZonedDateTime 进行测试。
   }
    
通过该方法可以验证 ZonedDateTime 的各种功能和特性。
    
      // 获取当前时间日期
ZonedDateTime 这个变量名为 date1 的对象,是通过 ZonedDateTime.parse 方法来进行解析的,解析的字符串内容为"2015-12-03T10:15:30+05:30[Asia/Shanghai]"。
      System.out.println("date1: " + date1);
        
ZoneId 的 id 为 "Europe/Paris",通过 ZoneId.of 方法获取到该 ZoneId
System.out.println("区域 ID:" + id);
        
获取系统默认的时区,将其赋值给 ZoneId 类型的变量 currentZone,即 ZoneId currentZone 等于 ZoneId.systemDefault() 所返回的时区对象。
System.out 会打印出 "当期时区: " 与 currentZone 进行拼接后的内容。 即会输出当前的时区信息,其中包含了 currentZone 的值。 它用于在控制台输出关于当期时区的相关信息。
   }
}

Lombok

现在许多 java 工程都应用了 Lombok ,由此可见它很实用。同时,也有反对的文章,可参见:

)。

lombok 能够以简单注解的形式,助力我们简化并消除一些必要但显得冗余的 Java 代码,像常见的 Getter&Setter、toString()、构造函数等。lombok 不但便于编写,还能让我们的代码更为简洁。lombok 提供了一个功能完备的 jar 包,可便捷地与我们的项目进行整合。

引入依赖:


    org.projectlombok
    lombok
    1.18.22
    provided

常见注解:

完整注解参见:

最新的 IDEA 已经将 Lombok 插件内置其中,它能够像丝滑般发挥实用作用。

Lombok 只是对代码进行了简化,然而对于背后 Java 语言的基本规范,我们是应当知晓的。这是大家必须要掌握的内容,希望大家能够进行自我检查。

Lombok实现浅析:

在使用 Lombok 时,只需添加相应的注解,就无需再为其编写任何代码。那么,自动生成的代码究竟是怎样产生的呢?

核心在于对注解的解析。JDK5 在引入注解的同时,还提供了两种解析的方式。

运行时能够被解析的注解,需要把@Retention设定为 RUNTIME,如此一来就能够借助反射获取到该注解。java.lang.reflect 反射包提供了一个接口叫 AnnotatedElement 。这个接口定义了获取注解信息的一些方法。Class、Constructor、Field、Method、Package 等都实现了该接口。对反射熟悉的朋友应该对这种解析方式很熟悉。

编译时解析有两种机制,分别简单描述下:

1)Annotation Processing Tool

apt 从 JDK5 开始出现,到 JDK7 时被标记为过期且不推荐使用,在 JDK8 中被彻底删除。从 JDK6 起,可以使用 Pluggable Annotation Processing API 来对其进行替换。apt 被替换主要有以下 2 点原因:

可插拔的注解处理 API 。

JSR 269 在 JDK6 被加入。它作为 apt 的替代方案而存在。此方案解决了 apt 的两个问题。javac 在执行时会调用实现了该 API 的程序。基于此,我们能够对编译器进行一些增强。

Lombok 实际上是一个实现了“JSR 269 API”的程序。在利用 javac 时,它发挥作用的具体流程具体如下:

javac 会对源代码展开分析,进而生成了一棵抽象语法树(AST)。在运行过程中,它会调用实现了“JSR 269 API”的 Lombok 程序。此时,Lombok 会对第一步得到的 AST 进行处理,去找到带有@Data 注解的类所对应的语法树(AST),接着对该语法树(AST)进行修改,添加 getter 和 setter 方法定义的相应树节点。之后,javac 会使用修改后的抽象语法树(AST)来生成字节码文件,也就是给 class 增加新的节点(代码块)。

读了 Lombok 源码后,发现对应注解的实现都在 HandleXXX 里。例如,@Getter 注解的实现在 HandleGetter.handle()。另外,还有一些其他类库也使用这种方式来实现,像 Google Auto、Dagger 等。

前面在讲 Spring AOP 时提到了动态代理实现,其底层是字节码增强,而这与 Lombok 的底层原理是一致的。这和元数据的理念极为相似,无论是在元数据层面,还是在元元数据层面,每一层抽象描述层的增强都能够让前一层的动态化能力得以实现。

关于字节码增强,感兴趣的同学自行baidu(

)

Swagger

Swagger 是一个用于生成、描述以及调用 RESTful 接口的 Web 服务。通俗来讲,它能把项目中所有(打算暴露的)接口呈现在页面上,同时还具备可以进行接口调用以及测试的功能。

Swagger 遵循了 OpenAPI 规范。OpenAPI 是 Linux 基金会的一个项目。它试图通过定义一种语言来规范 RESTful 服务开发过程,这种语言用于描述 API 格式或 API 定义。

Swagger 有以下 3 个重要的作用:

为什么需要swagger?

前面讲过,随着技术的发展,前后端分离架构越来越普及。我们曾了解到,以前在 jvm 内部调用别人的库需看 javadoc。后来,基于 RPC 的分布式调用,即便使用同种语言(java)也需看 javadoc,若不是同种语言调用则需要其他的调用描述。同理,前后端工程师需要一种统一沟通的接口描述方式,而 swagger 就是用来解决这个问题的。服务提供方主要采用基于 RESTful 规范的方式,其接口描述有规范,即 OpenAPI 规范,此规范也是后来面向 API 编程的一个基础设施。

常用注解:

表示标识这个类是swagger的资源

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读