如果 int 不继承 Object,那么"String.format(String, Object ...)"为什么要用 int 编译呢?



我读过这篇文章:int是Java中的对象吗?。

文章认为int不是从Object继承来的。如果是这样的话,那么为什么下面的代码编译时没有任何错误呢?假设int不是Object,并且format()方法的签名是public static String format(String format, Object... args),如文档所示:javadoc for String!

public class Testing {
    public static void main(String[] args) {
        int integer = 7;
        String str = String.format("%03d", integer);
        System.out.println(str);
    }
}

我也读过关于";自动装箱";。这到底意味着什么?在编译之前,是否所有的基元都被适当的Object替换?如果是这样的话,那么在使用intint[])的大阵列而不是IntegerInteger[])时,内存使用有什么优势吗?类似的论点也适用于double's等

欢迎任何见解。

它是由Autoboxing引起的。

以下是链接的Java文档中的一个小片段,它比我所能解释的更好:

Autoboxing是Java编译器进行的自动转换在基元类型及其对应的对象包装器之间类。例如,将int转换为Integer,将double转换为加倍,依此类推。如果转换为另一种方式,则为称为开箱。

以下是自动装箱的最简单示例:

Character ch = 'a';

本节中的其余示例使用泛型。如果你不是熟悉泛型的语法,请参阅泛型(更新版)课程

考虑以下代码:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(i);

尽管您将int值添加为基元类型,而不是整数对象,到李,代码编译。因为李是Integer对象,而不是int值的列表,您可能想知道为什么Java编译器不会发出编译时错误。编译器没有生成错误,因为它从i创建Integer对象并添加对象转换为li。因此,编译器将以前的代码转换为运行时如下:

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(Integer.valueOf(i));

调用String.format("%d",myInt)时,myInt自动(隐式)包装在Integer实例中,该实例扩展了Object,因此它进行编译。

关于阵列,由于某种原因,从primitiveType[]WrapperClass[]的转换不是自动的。如果您试图使用一个基元类型的数组,其中需要包装类的数组,则会导致编译错误。

与使用int相比,使用Integer会产生开销,因为您需要分配和存储引用。然而,当使用-128和127之间的Integer值时,这种开销是有限的,因为这些值是池化的(这意味着在该时间间隔中包装值的Integer的所有实例都指向unic引用)。

Autoboxing是编译器的帮助,它可以自动编译类似的东西

foo(i);

进入

foo(Integer.valueOf(i));

foo()接受Object类型的参数并向其传递基元类型(在本例中为int)时。它只是使代码更易于键入和阅读。

这就是这里发生的事情。String.format()方法需要对象作为参数。您正在向它传递一个基元类型,因此编译器会自动将它框为Integer。

相关内容

最新更新