我读过这篇文章:Is int an object in 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);
}
}
我还读过" Autoboxing"。这到底是什么意思?在编译之前,所有原语是否都被适当的Object
替换了?如果是这样,那么在使用大量int
int[]
(Integer
)而不是Integer[]
({{1}}时,是否有使用内存的优势)?类似论点也适用于双重等等。
欢迎任何见解。
答案 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()
方法期望对象作为参数。你传给它一个原始类型,所以编译器会为你自动将它变成一个整数。