为什么 Number 的自定义子项不继承自动装箱?

Why do custom children of Number not inherit auto-boxing?

我知道 Java 不支持自定义自动装箱,但我也注意到我可以扩展 Number 对象。由于数字对象本身似乎允许对基元进行自动装箱,因此可行:

Number val = 5; //This compiles no problem

但是,如果我扩展 Number 并尝试使用子类型,程序将无法编译:

MyNumber num = 5; //This does not compile :(

我知道这在 Java 中是不允许的,而且可能永远不会被允许,但是是什么机制导致了这种不连续性的发生? Number 的包装器功能是否在 class 本身之外的某个地方处理,或者是否有一些特殊的封装阻止了自定义包装器的创建?

5 是整数文字。因此它的类型是 int

由于它被分配给一个引用类型(数字)的变量,它被自动装箱为其包装器类型:java.lang.Integer。然后将此整数分配给变量,这是有效的,因为 Integer 是一个 数字:class 整数扩展了 class 数字。

相反,Integer 不扩展 MyNumber。因此,将 Integer 赋值给 MyNumber 类型的变量是无效的:Integer 不是 MyNumber.

所以这和开箱没有太大关系。这与你做不到的事实有关

MyNumber n = someInteger;

就像你不能那样

MyNumber n = someString;

: 类型不兼容。

自动装箱只是一种编译器优化。

语句Integer i= 5;的实际编译代码是Integer i = Integer.valueOf(5);

这不适用于 Number 的自定义子类,因为编译器不知道它们。您可以使用 IDE 或使用 javap 反编译代码并亲自查看。