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

时间:2014-10-04 08:16:18

标签: java

我读过这篇文章:Is int an object in Java?

在帖子中,有人认为int不是从Object继承的。如果是这样的话,为什么下面的代码编译没有任何错误?鉴于int不是Objectformat()方法的签名为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);
    }
}

我还读过" Autoboxing"。这到底是什么意思?在编译之前,所有原语是否都被适当的Object替换了?如果是这样,那么在使用大量int int[]Integer)而不是Integer[]({{1}}时,是否有使用内存的优势)?类似论点也适用于双重等等。

欢迎任何见解。

3 个答案:

答案 0 :(得分:5)

Autoboxing引起。

以下是链接的Java文档中的一小段代码,它比我更好地解释了它:

  

Autoboxing是Java编译器自动转换   原始类型与其对应的对象包装器之间   类。例如,将int转换为Integer,将double转换为a   双,等等。如果转换是另一种方式,那就是   称为拆箱。

     

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

Character ch = 'a';
  

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

     

请考虑以下代码:

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

虽然您将int值添加为基本类型,而不是   整数对象,li,代码编译。因为li是一个列表   整数对象,不是int值列表,你可能想知道为什么是Java   编译器不会发出编译时错误。编译器没有   生成错误,因为它从i创建一个Integer对象并添加   李的对象。因此,编译器将先前的代码转换为   在运行时跟随:

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

答案 1 :(得分:4)

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

关于数组,从primitiveType[]WrapperClass[]的转换由于某种原因不是自动的。如果您尝试使用包含类包装类数组的基本类型数组,则会导致编译错误。

与使用Integer相比,使用int会产生开销,因为您需要分配和存储引用。但是,当使用介于-128和127之间的Integer值时,此开销受到限制,因为这些值是合并的(这意味着在此间隔中包装值的Integer的所有实例都指向unic引用)。

答案 2 :(得分:3)

Autoboxing是编译器的帮助,可自动编译类似

的内容
foo(i);

进入

foo(Integer.valueOf(i));

foo()接受Object类型的参数时,你传递一个原始类型(在本例中为int)。它只是使代码更容易键入和读取。

这就是这里发生的事情。 String.format()方法期望对象作为参数。你传给它一个原始类型,所以编译器会为你自动将它变成一个整数。