2014-10-04 48 views
3

我看过这篇文章:Is int an object in Java?如果int不继承Object,那么为什么“String.format(String,Object ...)”用int的编译?

在帖子中,有人认为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); 
    } 
} 

我也读过关于“自动装箱”的内容。这究竟意味着什么?在编译之前所有的原语是否被合适的Object所取代?如果是这样,那么在Integer的(Integer[])上使用大量的intint[])时,是否有任何内存使用优势?类似的论点遵循双等。

任何见解是值得欢迎的。

回答

3

当调用String.format("%d",myInt)myInt自然而然(隐含地),因此它编译。

关于阵列,由于某些原因,从primitiveType[]WrapperClass[]的转换不是自动的。如果您尝试使用包装类的数组需要的基本类型的数组,它将导致编译错误。

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

+0

感谢您的回答,并感谢您澄清我对数组的怀疑。我从你的和其他答案中得出的结论是,自动装箱是在需要时在本地完成的,因此int []将比Integer []需要更少的空间。你能否详细说明最后的声明。你的意思是,如果Integer中包含的值介于-128和127之间,则不使用引用? – 2014-10-04 09:39:56

+0

在实例化-128和127之间的Integer时,如果该值已存在于池中,则JVM将首先在整数池中查找。如果有,则返回包含此值的现有Integer的引用,否则将创建一个新的Integer,将其添加到池中并返回。它使我们能够减少Integer引用的数量,因为大部分时间我们使用低整数值而不是高值。 – Dici 2014-10-04 12:09:59

+0

你可以阅读这个问题的3个第一个答案的一部分,以更好的方式解释它:http://stackoverflow.com/questions/13098143/java-integer-constant-pool – Dici 2014-10-04 12:14:06

3

自动装箱是从编译器,它会自动编译像

foo(i); 

foo(Integer.valueOf(i)); 

foo()使用对象类型作为自变量的帮助,你传递一个基本类型(INT,在这种情况下)。它只是让代码更容易打字和阅读。

而这就是发生在这里。 String.format()方法需要将对象作为参数。你将它传递给一个原始类型,所以编译器会自动将它自动包装为一个Integer。

+0

谢谢你的回答。 – 2014-10-04 09:47:50

5

它是由Autoboxing造成的。

这里是链接Java文档一个小片段,说明它不是更好,我可以:

自动装箱是自动转换,Java编译器,使 基本类型及其相应的对象包装 类之间。例如,将int转换为整数,双精度转换为双精度,等等。如果转换以其他方式进行,则这是 称为取消装箱。

下面是自动装箱的最简单的例子:

Character ch = 'a'; 

的本节中使用泛型实施例中的其余部分。如果您不是 但仍然熟悉泛型语法,请参阅泛型(更新) 课程。

考虑下面的代码:

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

虽然你加INT值作为原始类型,而不是 Integer对象,李,代码编译。因为li是整数对象列表 ,而不是int值列表,所以您可能想知道为何Java 编译器不会发出编译时错误。编译器不会 生成一个错误,因为它会从i创建一个Integer对象,并将该对象添加到li中。因此,编译器转换之前的代码到 在运行时执行以下操作:包装在一个Integer实例,它延伸Object

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

谢谢你的回答。 – 2014-10-04 09:48:07

相关问题