跳到主要内容
Java 常用 API 与日期工具详解及异常处理 | 极客日志
Java java
Java 常用 API 与日期工具详解及异常处理 综述由AI生成 介绍 Java 常用 API 中的日期时间处理工具,包括 Date、Calendar、DateFormat 和 SimpleDateFormat 类的使用方法及注意事项。重点讲解了 Calendar 月份索引从 0 开始及日期为 0 时的特殊规则,以及时间戳计算中 long 强转的重要性。此外,还详细阐述了 Java 异常处理机制,涵盖异常继承体系、捕获与抛出语法、自定义异常实现及最佳实践原则。通过多个代码示例演示了获取月份天数、时区换算及成绩校验的实际应用。
微码行者 发布于 2026/3/24 更新于 2026/5/10 23K 浏览常用 API
日期工具
Date
Date 类用来处理日期和时间,但是该类的大部分构造器、方法均已过时。
- 常用的构造方法
public Date () { }
public Date (long date) { }
- 常用的成员方法
public boolean after (Date when ) { }
public boolean before (Date when ) { }
public long getTime () { }
public void setTime (long time) { }
Calendar
相比于 Date 类,Calendar 类可以更好地处理日期和时间。
Calendar 是一个抽象类,所以不能通过构造器创建 Calendar 对象。
Calendar 类提供了静态方法 getInstance(),用以创建实例。
- Calendar 类提供了与 Date 互转的方法
public final Date getTime () { }
public { }
final
void
setTime
(Date date)
- Calendar 类常用的成员方法
public int get (int field) {}
public void set (int field, int amount) {}
public void set (int year, int month, int date) {}
public void set (int year, int month, int date, int hourOfDay, int minute, int second) {}
- Calendar 类常用的静态变量
YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND
DateFormat DateFormat 用于实现日期的格式化,它是一个抽象类,提供了如下静态方法以创建实例:
public final static DateFormat getDateInstance () {}
public final static DateFormat getTimeInstance () {}
public final static DateFormat getDateTimeInstance () {}
同时,DateFormat 提供了如下常用的成员方法:
public final String format (Date date) {}
public Date parse (String source) throws ParseException {}
SimpleDateFormat SimpleDateFormat 是 DateFormat 的子类,提供了更简单的格式化方案,该类提供了如下常用的构造器,常用的成员方法则与 DateFormat 一致。
public SimpleDateFormat (String pattern) {}
练习:输出某一年的各个月份的天数 Calendar calendar = Calendar.getInstance();
for (int month = 1 ; month <= 12 ; month++) {
calendar.set(year, month, 0 );
System.out.println(year + "年" + month + "月:" + calendar.get(calendar.DAY_OF_MONTH) + "天" );
}
DAY_OF_MONTH 是 java.util.Calendar 类的静态常量(int 类型)
Calendar 的月份是 0 基索引 :0 代表 1 月,1 代表 2 月,……,11 代表 12 月,这是 Calendar 最经典的'坑'。
日期传入 0 的特殊规则 :Calendar 的 set 方法中,日期字段传入 0,代表取「上一个月的最后一天」 。
当 month=1 时,set(year, 1, 0) → 月份 1 对应日历的 2 月,日期 0 → 自动回退到 2 月的上一个月(1 月)的最后一天。
此时调用 get(Calendar.DAY_OF_MONTH),拿到的就是 1 月最后一天的数值,也就是 1 月的总天数。
同理,month=12 时,set(year, 12, 0) → 月份 12 对应次年 1 月,日期 0 → 回退到当年 12 月的最后一天,拿到 12 月的总天数。
练习:日期换算
String[] arr = str1.split(" " );
if (arr.length != 6 ) {
System.out.println("您输入的数据不合理" );
} else {
String str = arr[0 ] + "-" + arr[1 ] + "-" + arr[2 ] + " " + arr[3 ] + ":" + arr[4 ] + ":" + arr[5 ];
Date date = sdf.parse(str);
System.out.println("北京时间为:" + sdf.format(date.getTime()));
System.out.println("纽约时间为:" + sdf.format(date.getTime() - (long ) 12 * 60 * 60 * 1000 ));
}
parse 是 SimpleDateFormat 类的核心方法,作用是把符合指定格式的「日期时间字符串」,解析转换为 java.util.Date 日期对象 ,是「字符串→日期对象」的转换方法。
format 是 parse 的反向操作,作用是把 Date 对象 /long 类型的时间戳,按照 sdf 指定的格式模板,转换为人类可读的日期时间字符串 。
强转 long 的 2 个核心原因
原因 1:从根源上规避整数溢出,是行业通用安全规范 如果不加强转,12*60*60*1000 的所有操作数都是 int,运算结果也是 int。虽然 12 小时的毫秒数 43200000,刚好在 int 范围内,但这是非常脆弱的写法 :
若后续修改数值(比如计算 30 天、100 天的毫秒数),30*24*60*60*1000=2592000000,已经超出 int 最大值,会直接溢出变成负数 -1702967296,导致时间计算完全错误。
第一个操作数变成 long 类型,后续所有乘法运算都会自动触发类型提升,全程以 long 类型运算,无论数值多大,都不会发生溢出。
这是 Java 处理时间毫秒数的通用最佳实践 ,因为时间戳本身就是 long 类型,加减的数值也必须保证是 long 类型,从根源上避免 bug。
原因 2:和 date.getTime() 的 long 类型匹配,避免隐式转换风险 date.getTime() 返回的是 long 类型(64 位整数),如果减数是 int 类型,Java 会自动把 int 提升为 long 再做减法。
异常处理
Java 语言具有如下的异常处理机制:当程序运行出现意外情形时,系统会自动生成一个异常对象来通知程序。
在程序中,我们可以使用特定的语句来捕获异常对象,读取对象中的信息,进而做出处理。
也可以使用特定的语句抛出异常对象,将这个异常对象交给程序的调用者处理。
异常的继承体系
- 所有的非正常情况被分为两类: 错误(Error)和异常(Exception),其中 Error 代表虚拟机相关问题,一般无法处理,也无需处理。
- 所有的 Exception 被分为两类
RuntimeException,代表运行时异常,程序可以显式处理这种异常,也可以不处理,而是交给顶层调用者统一处理。
非运行时异常(Checked 异常),程序必须显式地处理这种异常,否则在编译阶段会发生错误,导致程序无法通过编译。
捕获异常
语法: try { 业务逻辑代码 } catch (AException e) { A 异常的处理代码 } catch (BException e) { B 异常的处理代码 } ... finally { 回收资源代码 }
说明:
无论哪行代码发生异常,系统都会生成一个异常对象,这与 try...catch...语句没有关系;
若程序没有对这个异常对象做任何处理,则程序在此退出;
创建异常对象后,JVM 会寻找可以处理它的 catch 块,并将异常对象交给这个 catch 块去处理;
程序应该先处理小异常、再处理大异常,即将处理父类异常的 catch 块放在处理子类异常的 catch 块之后;
finally 块中代码总是会被执行,它必须位于 try、catch 之后,通常用来释放资源;
try 是必须的,catch、finally 是可选的,但 catch、finally 二者之中至少要出现一个。
声明抛出异常
语法: throws ExceptionClass1, ExceptionClass2, ...
说明:
throws 语句用于标识某方法可能抛出的异常,它必须位于方法签名之后;
throws 语句声明抛出异常后,程序中旧无需使用 try 语句捕获该异常了;
在重写时,子类方法声明抛出的异常类型不能比父类方法声明抛出的异常类型大。
抛出异常
语法:
说明:
throw 语句用于在程序中主动抛出一个异常;
throw 语句抛出的不是异常类型,而是一个异常实例;
对于主动抛出的异常,也可以采用 try 块捕获,或者采用 throws 语句向外抛出。
异常的处理原则
不要多度的使用异常:
不要用异常处理代替错误处理代码,不要用异常处理代替流程控制语句;
不要忽略捕获的异常:
对于捕获到的异常,要进行合适的修复,对于不能处理的部分,应该抛出新的异常;
不要直接捕获所有的异常:
应对不同的异常做出有针对性的处理,而捕获所有的异常,容易压制(丢失)异常;
不要使用过于庞大的 try 块:
庞大的 try 块会导致业务过于复杂,不利于分析异常的原因,也不利于程序的阅读及维护。
练习:判断学生成绩 import java.util.*;
public class Main {
public static void main (String[] args) {
Scanner scanner = new Scanner (System.in);
int score = scanner.nextInt();
try {
if (score >= 0 && score <= 100 ) {
System.out.println(score);
}
else {
throw new ScoreException ("分数不合法" );
}
} catch (ScoreException e) {
System.out.println(e.getMessage());
}
}
}
class ScoreException extends Exception {
ScoreException(String message) {
super (message);
}
}
getMessage(): 获取异常对象中携带的、自定义的异常详细描述文本
当分数不合法时,new ScoreException("分数不合法") 会创建一个异常对象,把 "分数不合法" 通过构造方法,最终存到 detailMessage 里。
catch 块捕获到这个异常对象,赋值给变量 str。
str.getMessage() 会读取异常对象里存储的 detailMessage,也就是传入的 "分数不合法",最终打印输出。
super(message) 的核心作用:'让父类帮忙初始化数据'super 在这里的意思是 '父类的 ',super(message) 就是 '调用父类中接收一个 String 参数的构造方法 '。
public ScoreException (String message) {
super (message);
}
为什么必须写 super(message)?(不写会怎样?) 父类数据的封装性 Throwable 里的 detailMessage 是一个 private(私有)变量。子类 ScoreException无权直接修改 它。所以必须通过父类提供的 '构造方法入口'(即 super(message))来间接赋值。
如果不写,信息就丢了 如果你只写 super()(不传参数),或者干脆不写 super(编译器会自动补一个无参的 super()),那么父类里的 detailMessage 就会是 null。
super 关键字的两种常见用法用法 示例 含义 1. 调用父类构造方法 super(message);在子类构造方法的第一行调用,用于初始化父类的成员变量。 2. 调用父类的普通方法/变量 super.someMethod();在子类方法中调用父类被重写(Override)的方法,或者访问父类的成员变量。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online