首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 核心類庫深度解析:System、Runtime、Math、Date 與 Calendar 實戰指南

     編輯:Java 綜合教學

前言

在 Java 開發中,java.lang 與 java.util 包下的核心工具類是我們每天打交道最頻繁的 API。掌握 System、Runtime、Math、Date 以及 Calendar 的正確用法,不僅能提升開發效率,更能避免許多常見的坑。本文將通過實戰代碼示例,系統梳理這五大核心類的關鍵方法與最佳實踐。

一、System 類:系統級操作的入口

System 類的字段和方法均為 static,提供了標準輸入/輸出、系統屬性訪問、環境變量讀取、GC 觸發以及高精度計時等功能。

1.1 核心方法速查

  • currentTimeMillis():返回當前時間與 UTC 1970-01-01 00:00:00 的毫秒差,常用於性能計時。
  • nanoTime():返回納秒級時間戳,專為測量代碼執行耗時設計,精度更高。
  • getProperty(key) / setProperty(key, value):讀寫系統屬性(如 line.separator、java.version)。
  • getProperties():一次性獲取所有系統屬性,返回 Properties 對象。
  • arraycopy():高效的數組拷貝原生方法,效率遠超手寫循環。
  • gc():建議 JVM 執行垃圾回收(不保證立即執行)。

1.2 實戰代碼:性能計時與系統屬性遍歷

public class SystemDemo {
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");

    public static void main(String[] args) {
        // 1. 計時代碼執行時間
        long start = System.currentTimeMillis();
        // 模擬業務邏輯
        int sum = 0;
        for (int i = 0; i < 1_000_000; i++) sum += i;
        long end = System.currentTimeMillis();
        System.out.println("耗時:" + (end - start) + " ms");

        // 2. 遍歷所有系統屬性
        Properties props = System.getProperties();
        for (String key : props.stringPropertyNames()) {
            System.out.println(key + " = " + props.getProperty(key));
        }

        // 3. 自定義屬性與換行符
        System.setProperty("app.name", "MyApp");
        System.out.println("App Name: " + System.getProperty("app.name"));
        System.out.println("Hello" + LINE_SEPARATOR + "World");
    }
}

System 類運行示例

二、Runtime 類:與 JVM 運行環境交互

Runtime 採用單例模式(getRuntime()),每個 Java 應用僅有一個實例,提供了與運行環境交互的能力:執行外部命令、獲取內存信息、添加關閉鉤子等。

2.1 常見應用場景

  • 啟動外部進程:exec("notepad.exe") 或 exec("cmd /c dir")。
  • 內存監控:totalMemory()、freeMemory()、maxMemory()。
  • 關閉鉤子:addShutdownHook(Thread hook) 在 JVM 關閉前執行清理邏輯。

2.2 實戰代碼:啟動記事本並 5 秒後強制關閉

public class RuntimeDemo {
    public static void main(String[] args) throws IOException, InterruptedException {
        Runtime rt = Runtime.getRuntime();
        // 啟動 notepad 並打開指定文件
        Process p = rt.exec("notepad.exe D:\\1.txt");
        // 等待 5 秒
        Thread.sleep(5000);
        // 銷毀進程
        p.destroy();
        System.out.println("進程已終止");
    }
}

三、Math 類:數學運算工具箱

Math 所有方法均為 static,涵蓋了取整、冪運算、三角函數、對數、隨機數等常用數學運算。

3.1 高頻方法對照表

方法說明示例
ceil(double a)向上取整(返回 ≥ 參數的最小整數)Math.ceil(12.3) → 13.0
floor(double a)向下取整(返回 ≤ 參數的最大整數)Math.floor(12.9) → 12.0
round(double a)四捨五入Math.round(12.5) → 13
pow(double a, double b)a 的 b 次冪Math.pow(2, 10) → 1024.0
random()返回 [0.0, 1.0) 隨機 double0.732...
abs(int a)絕對值Math.abs(-5) → 5
max/min最大/最小值Math.max(3, 7) → 7

3.2 進階隨機數:Random 類

對於需要生成指定範圍整數、高性能或多線程場景,推薦使用 java.util.Random 或 ThreadLocalRandom(JDK 7+)。

Random r = new Random();
// 生成 0~9 的隨機整數
for (int i = 0; i < 10; i++) {
    System.out.println(r.nextInt(10));
}
// 生成高斯分佈隨機數
System.out.println(r.nextGaussian());

四、Date 與 DateFormat:傳統日期時間處理

注意:java.util.Date 及 SimpleDateFormat 為舊版 API(JDK 1.0/1.1),存在線程不安全、設計混亂(年份從 1900 開始、月份 0~11)等問題。新項目強烈建議使用 JDK 8+ 的 java.time 包(LocalDateTime、DateTimeFormatter 等)。本節僅作為維護舊代碼的參考。

4.1 Date 核心機制

  • 本質:封裝了一個 long 型毫秒時間戳(UTC 1970-01-01 起)。
  • 構造方法:new Date()(當前時間)、new Date(millis)(指定毫秒值)。
  • 轉換:getTime() → 毫秒值;setTime(millis) → 修改時間。

4.2 日期格式化與解析

Date now = new Date();

// 1. 內建風格格式化
DateFormat df1 = DateFormat.getDateInstance(DateFormat.FULL);      // 2024年1月15日 星期一
DateFormat df2 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT); // 2024年1月15日 14:30

// 2. 自定義模式(線程不安全,請勿作為靜態共享變量)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(now);   // 日期 → 字符串
Date parsed = sdf.parse("2024-01-15 14:30:00"); // 字符串 → 日期

4.3 實戰:計算兩日期相差天數

public static int daysBetween(String d1, String d2) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date1 = sdf.parse(d1);
    Date date2 = sdf.parse(d2);
    long diff = Math.abs(date1.getTime() - date2.getTime());
    return (int) (diff / (1000 * 60 * 60 * 24));
}
// 測試
System.out.println(daysBetween("2012-03-17", "2012-04-06")); // 輸出 20

五、Calendar 類:日曆運算的瑞士軍刀

Calendar 為抽象類,通過 getInstance() 獲取具體實現(通常是 GregorianCalendar)。它提供了豐富的字段操作(年、月、日、時、分、秒、毫秒、星期等)與日期運算(add、roll)。

5.1 關鍵字段常量

  • YEAR、MONTH(0~11)、DAY_OF_MONTH、HOUR_OF_DAY(24 制)、MINUTE、SECOND、MILLISECOND
  • DAY_OF_WEEK:1=星期日 … 7=星期六
  • WEEK_OF_YEAR、WEEK_OF_MONTH

5.2 實戰代碼:獲取當前日期時間、判斷閏年二月天數

public class CalendarDemo {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        printCalendar(c); // 2024年1月15日 星期一 14:30:45

        // 判斷 2024 年二月天數(閏年 29 天)
        printFebDays(2024);
    }

    static void printCalendar(Calendar c) {
        int y = c.get(Calendar.YEAR);
        int m = c.get(Calendar.MONTH) + 1; // 月份需 +1
        int d = c.get(Calendar.DAY_OF_MONTH);
        int w = c.get(Calendar.DAY_OF_WEEK);
        int hh = c.get(Calendar.HOUR_OF_DAY);
        int mm = c.get(Calendar.MINUTE);
        int ss = c.get(Calendar.SECOND);
        System.out.printf("%d年%02d月%02d日 %s %02d:%02d:%02d%n",
                y, m, d, weekName(w), hh, mm, ss);
    }

    static void printFebDays(int year) {
        Calendar c = Calendar.getInstance();
        c.set(year, Calendar.FEBRUARY, 1);      // 設置為 2 月 1 日
        c.add(Calendar.DAY_OF_MONTH, -1);       // 回退一天 → 1 月 31 日 或 2 月 29/28 日
        printCalendar(c);
    }

    static String weekName(int w) {
        String[] weeks = {"", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        return weeks[w];
    }
}

Calendar 運行結果

六、總結與最佳實踐建議

  1. 新項目優先使用 java.time 包:LocalDateTime、ZonedDateTime、DateTimeFormatter 線程安全、API 直觀、功能強大。
  2. 性能計時用 System.nanoTime(),而非 currentTimeMillis()。
  3. 隨機數場景區分:一般用 ThreadLocalRandom;安全敏感用 SecureRandom;並發高用 Random 子類或 SplittableRandom。
  4. 避免在多線程中共享 SimpleDateFormat,改用 ThreadLocal 或 DateTimeFormatter(不可變、線程安全)。
  5. Runtime.exec() 執行外部命令時,務必處理輸入/輸出/錯誤流,否則可能導致進程阻塞或僵屍進程。

掌握這些核心類的精髓,能讓你在日常開發、性能調優、系統集成等場景中遊刃有餘。建議收藏備查,並在實戰中不斷驗證與深化理解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved