Long.getLong(String nm)java.lang.Long 类中的一个静态工具方法,用于从 系统属性(System Properties) 中读取指定名称的属性值,并尝试将其解析为 Long 对象。如果属性不存在或解析失败,可以返回默认值。


📚 一、方法定义

1. Long.getLong(String nm)

public static Long getLong(String nm)
  • 功能:获取系统属性 nm 的值,解析为 Long
  • 返回值
    • 如果属性存在且能解析为 long,返回对应的 Long 对象;
    • 否则返回 null

2. Long.getLong(String nm, long val)

public static Long getLong(String nm, long val)
  • 功能:获取系统属性 nm,解析为 Long,如果失败则返回默认值 val
  • 返回值Long 对象(不会为 null)。

3. Long.getLong(String nm, Long val)

public static Long getLong(String nm, Long val)
  • 功能:同上,但默认值是 Long 对象。
  • 返回值Long 对象。

🧩 二、工作原理

该方法按以下顺序解析属性值:

  1. System.getProperty(nm) 获取字符串值;
  2. 尝试按以下格式解析:
    • 十进制(如 "123"
    • 十六进制(如 "0x123", "0X123", "#123"
    • 八进制(如 "0123",以 0 开头)
  3. 使用 Long.decode(String) 进行解析(支持前缀);
  4. 解析成功 → 返回 Long.valueOf(parsedValue)
  5. 失败或属性不存在 → 返回 null 或默认值。

✅ 内部调用的是 Long.decode(),因此支持 0x#0 等前缀。


💡 三、示例代码

示例 1:基本使用(无默认值)

public class GetLongExample {
    public static void main(String[] args) {
        // 设置系统属性(通常通过 -D 参数传入)
        System.setProperty("app.timeout", "5000");
        System.setProperty("app.buffer.size", "0x1000");
        System.setProperty("app.mode", "invalid");

        // 读取属性
        Long timeout = Long.getLong("app.timeout");
        System.out.println("Timeout: " + timeout); // 5000

        Long bufferSize = Long.getLong("app.buffer.size");
        System.out.println("Buffer Size: " + bufferSize); // 4096(0x1000)

        Long mode = Long.getLong("app.mode");
        System.out.println("Mode: " + mode); // null(解析失败)

        Long missing = Long.getLong("app.missing");
        System.out.println("Missing: " + missing); // null(属性不存在)
    }
}

示例 2:使用默认值

// 使用 long 默认值
Long threads = Long.getLong("app.thread.count", 10L);
System.out.println("Thread Count: " + threads); // 若未设置,输出 10

// 使用 Long 对象默认值
Long defaultVal = Long.valueOf(100);
Long cacheSize = Long.getLong("app.cache.size", defaultVal);

示例 3:通过 JVM 参数传入(推荐方式)

在运行 Java 程序时使用 -D 参数:

java -Dapp.port=8080 -Dapp.timeout=30000 MyApp
public class MyApp {
    public static void main(String[] args) {
        Long port = Long.getLong("app.port", 8080L);      // 8080 或 8080
        Long timeout = Long.getLong("app.timeout", 60000L); // 30000 或 60000

        System.out.println("Port: " + port);
        System.out.println("Timeout: " + timeout);
    }
}

🔄 四、支持的数值格式

getLong() 内部使用 Long.decode(),因此支持:

格式 示例
十进制 "123"
十六进制(0x) "0xFF", "0X1A"
十六进制(#) "#FF"
八进制(0开头) "012" → 十进制 10

❌ 不支持二进制(如 "0b1010"


⚠️ 五、注意事项

注意点 说明
依赖系统属性 只能读取 System.getProperties() 中的值,不能读取环境变量或命令行参数(除非通过 -D 设置)
返回值可能为 null 无默认值版本可能返回 null,使用前需判空
自动识别进制 支持 0x, #, 0 前缀,适合配置灵活输入
线程安全 System.getProperty()getLong() 是线程安全的
性能 属于轻量级操作,适合启动时配置读取,不建议高频调用

❌ 六、常见错误

错误 说明 修复方式
返回 null 未处理 导致 NullPointerException 使用带默认值版本或判空
期望读取环境变量 getLong() 不读取 System.getenv() 改用 System.getenv() 手动解析
误认为可设置属性 getLong() 是读取,不是设置 使用 System.setProperty() 设置
解析失败静默忽略 可能掩盖配置错误 可封装日志或异常处理

🛠️ 七、使用技巧

1. 封装健壮的配置读取

public class Config {
    public static long getLongProperty(String key, long defaultValue) {
        Long value = Long.getLong(key, defaultValue);
        if (value == null) {
            System.err.println("Invalid long property: " + key + ", using default: " + defaultValue);
            return defaultValue;
        }
        return value;
    }
}

// 使用
long timeout = Config.getLongProperty("app.timeout", 30000L);

2. 支持更多格式(如 K/M/G)

public static Long getLongWithUnit(String key, long defaultValue) {
    String valueStr = System.getProperty(key);
    if (valueStr == null) return Long.valueOf(defaultValue);

    valueStr = valueStr.trim().toLowerCase();
    long multiplier = 1;
    if (valueStr.endsWith("k")) {
        multiplier = 1_000;
        valueStr = valueStr.substring(0, valueStr.length() - 1);
    } else if (valueStr.endsWith("m")) {
        multiplier = 1_000_000;
        valueStr = valueStr.substring(0, valueStr.length() - 1);
    } else if (valueStr.endsWith("g")) {
        multiplier = 1_000_000_000;
        valueStr = valueStr.substring(0, valueStr.length() - 1);
    }

    try {
        return Long.valueOf(Long.parseLong(valueStr) * multiplier);
    } catch (NumberFormatException e) {
        return Long.valueOf(defaultValue);
    }
}

🏆 八、最佳实践

场景 推荐做法
✅ 读取 JVM 启动参数 使用 -Dkey=value + Long.getLong(key, default)
✅ 配置默认值 优先使用带默认值的重载方法
✅ 处理 null 避免自动拆箱导致 NPE
✅ 日志记录 在返回默认值时输出警告日志
❌ 高频调用 避免在循环中调用,应缓存结果
❌ 替代配置框架 复杂配置应使用 PropertiesConfig 库等

📝 九、总结

项目 内容
核心功能 从系统属性读取 long 值,支持默认值
关键优势 支持 0x, #, 0 前缀(通过 decode),返回 Long 对象
典型用途 JVM 参数解析、系统配置读取、调试开关
注意事项 可能返回 null,仅读取系统属性,不支持环境变量
性能 轻量,适合启动时使用
推荐使用 ✅ 在通过 -D 传参时首选

一句话掌握

Long.getLong("key", defaultValue) 安全地从 JVM 系统属性中读取 long 配置值,支持十进制、十六进制、八进制格式,是轻量级配置管理的利器。