1. 概述

本文深入解析 Java 中的 Number 类。✅
我们将先了解 Number 类的作用及其核心方法,然后探讨它的主要子类实现。对于有经验的开发者来说,这是一次对基础类的“温故知新”——看似简单,但有些细节你可能一直没注意过。

2. Number 类简介

Numberjava.lang 包中的一个抽象类,作为所有数值包装类的统一父类。常见的子类包括:

  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double

它的核心作用是提供一套标准方法,用于将包装类中的数值转换为各种基本类型(primitive types):byteshortintlongfloatdouble

该类定义了 4 个抽象方法,由子类具体实现:

  • intValue()
  • longValue()
  • floatValue()
  • doubleValue()

此外,它还提供了两个具体实现方法

  • byteValue()
  • shortValue()

这两个方法的默认实现是基于 intValue() 进行强制类型转换的。子类可以重写,但大多数情况下直接继承默认行为。

💡 提示:关于包装类的自动装箱/拆箱机制,本文不展开。如果你还不熟悉 Integer.valueOf(100)new Integer(100) 的区别,建议先补一下基础。

3. 具体方法解析

3.1 shortValue()

将当前 Number 对象的值转换为 short 类型返回。

默认实现是 (short)intValue(),但子类如 DoubleFloat 会根据自身值做截断处理。

示例:Doubleshort

@Test
public void givenDoubleValue_whenShortValueUsed_thenShortValueReturned() {
    Double doubleValue = Double.valueOf(9999.999);
    assertEquals(9999, doubleValue.shortValue());
}

⚠️ 注意:小数部分直接被截断(truncated),不是四舍五入!

3.2 byteValue()

将当前 Number 对象的值转换为 byte 类型返回。

同样,默认基于 intValue() 强转,超出 byte 范围(-128 ~ 127)会溢出。

示例:Floatbyte

@Test
public void givenFloatValue_whenByteValueUsed_thenByteValueReturned() {
    Float floatValue = Float.valueOf(101.99F);
    assertEquals(101, floatValue.byteValue());
}

✅ 踩坑提醒:Float.valueOf(300.0F).byteValue() 结果是 44(因为 300 % 256 = 44),这种溢出问题在数据解析时容易被忽略。

4. 抽象方法详解

这些方法由子类实现,但使用方式统一,是 Number 多态性的体现。

4.1 intValue()

返回当前数值的 int 表示形式。

示例:Longint

@Test
public void givenLongValue_whenInitValueUsed_thenInitValueReturned() {
    Long longValue = Long.valueOf(1000L);
    assertEquals(1000, longValue.intValue());
}

⚠️ 警告:这是窄化转换(narrowing primitive conversion)。如果 Long 值超出 int 范围(±21亿左右),会发生溢出,结果不可预期。例如:

Long big = 3_000_000_000L;
System.out.println(big.intValue()); // 输出 -1294967296(溢出!)

4.2 longValue()

返回当前数值的 long 形式。

示例:Integerlong

@Test
public void givenIntegerValue_whenLongValueUsed_thenLongValueReturned() {
    Integer integerValue = Integer.valueOf(100);
    assertEquals(100, integerValue.longValue());
}

✅ 这是扩展转换(widening primitive conversion),安全无损,不会丢失精度。

4.3 floatValue()

将数值转换为 float 类型返回。

示例:Shortfloat

@Test
public void givenShortValue_whenFloatValueUsed_thenFloatValueReturned() {
    Short shortValue = Short.valueOf(127);
    assertEquals(127.0F, shortValue.floatValue(), 0);
}

✅ 同样是扩展转换,安全。但注意 float 精度有限,大整数可能丢失低位精度。

4.4 doubleValue()

将数值转换为 double 类型返回。

示例:Bytedouble

@Test
public void givenByteValue_whenDoubleValueUsed_thenDoubleValueReturned() {
    Byte byteValue = Byte.valueOf(120);
    assertEquals(120.0, byteValue.doubleValue(), 0);
}

✅ 扩展转换,安全。double 是 Java 中精度最高的浮点类型,通常作为“最终转换目标”。

5. 总结

  • Number 类通过抽象方法统一了数值类型的转换接口。
  • byteValue()shortValue() 是具体方法,基于 intValue() 实现。
  • 所有转换方法都可能涉及精度丢失或溢出,使用时务必注意原始值范围。
  • intValue()窄化转换,风险最高,尤其处理 Long 时要格外小心。
  • longValue()floatValue()doubleValue() 通常是安全的扩展转换。

💡 实际开发建议:
在涉及类型转换的场景(如 JSON 解析、数据库读取),尽量使用 longValue()doubleValue() 获取更高精度的值,避免因自动转 int 导致溢出。

完整示例代码已托管至 GitHub:https://github.com/baeldung/tutorials/tree/master/core-java-modules/core-java-numbers-3


原始标题:Guide to the Number Class in Java