发布于2026-07-07 阅读(0)
扫一扫,手机访问
本文解析 Number x = 3; 赋值背后的自动装箱机制,阐明为何可调用 intValue() 和 doubleValue(),并澄清 Number 作为抽象类不可实例化,但可作为引用类型指向具体子类(如 Integer)对象。
在 Ja va 的世界里,Number x = 3; 这行代码看似简单,背后却藏着两个关键机制:自动装箱与多态引用。不少初学者会困惑——Number 明明是抽象类,怎么能直接赋一个整数?调用 intValue() 和 doubleValue() 又是怎么工作的?别急,咱们一步步拆开看。
Number 是 ja va.lang 包下的抽象基类,所有数值包装类(Integer、Double、Long 等)都继承自它。它声明了 byteValue()、shortValue()、intValue()、longValue()、floatValue() 和 doubleValue() 这些抽象方法——这意味着 你没法直接 new Number(),但它可以作为一个统一的引用类型,指向任意子类的实例。
回到那段示例代码:
public class Test {
public static void main(String[] args) {
Number x = 3;
System.out.println(x.intValue()); // 输出: 3
System.out.println(x.doubleValue()); // 输出: 3.0
}
}
关键就在 Number x = 3; 这一行。这里发生的是 自动装箱(autoboxing),而不是什么隐式类型转换或向上转型。编译器在背后悄悄把它重写成了:
Number x = Integer.valueOf(3); // ✅ 自动装箱:int → Integer → 赋值给 Number 引用
看到没?3(原始 int 类型)先被装箱成 Integer 实例(由 Integer.valueOf(3) 返回),而 Integer 恰恰是 Number 的一个具体子类。于是,这个 Integer 对象就能顺理成章地赋值给类型为 Number 的变量 x。此时 x 的静态类型是 Number,但它实际指向的是一个活生生的 Integer 对象。
当你调用 x.intValue() 时,Integer 重写了这个抽象方法,直接返回它内部存储的 int 值;而 x.doubleValue() 则执行 Integer 的实现——先取出内部 int 值,再通过 宽化原始类型转换(widening primitive conversion, JLS §5.1.2) 转为 double。这个转换是精确无损的,因为 int 的全范围都能被 double 精确表示。
⚠️ 几个需要留神的地方:
new Double(3.14)、new Long(100L) 都可以,但运行时的行为取决于实际对象的真实类型——这就是多态的魅力。总结一下:Number x = 3; 的本质就是 自动装箱 + 多态引用——编译器自动把 int 装箱成 Integer,再利用继承关系把子类对象赋给父类引用。所有方法调用在运行时动态绑定到实际的对象类型。这既是 Ja va 面向对象灵活性的体现,也是抽象类设计价值的绝佳例子。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8