int值和Integer对象是在哪里创建的?

9

当我们初始化一些整数值时,例如

int a = 10; 

或者
Integer b = new Integer(20);
Integer b = 30;

这些对象在内存中是在哪里创建的?

是否存在像字符串池(String-Pool)一样的整数池(Integer-Pool)的概念?


请参见以下链接:https://dev59.com/QnTYa4cB1Zd3GeqPrCP1 - ka4eli
3个回答

4

大多数JVM(即使是64位的)使用32位引用。(新的JVM对于近32GB的堆使用32位引用)引用在堆栈或CPU寄存器中,通常不计算。整数分配在堆上。

Integer i = new Integer(1); // creates a new object every time.
Integer j = 1; // use a cached value.

Integer a;会在堆栈中分配内存来保存引用值,并初始化为null

newheap内存中创建实例。


我们知道代码 Integer a = 127; 是自动装箱的一个例子,编译器会自动将这行代码转换为 Integer a = Integer.valueOf(127);。因此,返回这些整数对象的是 Integer.valueOf() 方法,这意味着该方法在幕后必须要做一些事情。我有点困惑,Integer a; 在堆上还是栈上? - Ulviyya Ibrahimli
1
https://dzone.com/articles/java-integer-cache-why-integervalueof127-integerva - Ulviyya Ibrahimli

3
使用new关键字创建的对象存储在堆上。变量(对这些对象的引用)和原始类型如int存储在程序的堆栈中。在Java中,Integer不是特殊的类。您可以使用算术运算符,它是不可变的,甚至可以在-128到127的范围内使用==进行相等性测试(因为这些值已经被缓存)。像我们对字符串使用的String-Pool一样,是否有类似于Integer-Pool的概念?打开java.lang.Integer的代码并查看valueOf方法。很明显他们确实使用了一个Integer池。
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

此外,我认为这张图片对您会有所帮助:

enter image description here



对象[...]存储在堆上。也许你应该阅读一些关于逃逸分析的内容。实际上,这使得你的陈述不完全正确。 - Seelenvirtuose
是的,让我们深入探讨一下,向正在学习面向对象编程的人解释这个问题。在他理解堆栈之间的区别之前,我们应该首先讲解逃逸分析和JVM增强。 - darijan
是的,我知道不应该用太多技术细节来压倒初学者。然而,这个说法本身并不正确。其他读者可能更加高级。一个好的解释应该简短而准确。让读者自己决定是否深入了解细节(超链接,嘿?)。 - Seelenvirtuose
当我看到别人的评论有改进的空间时,我会编辑它。出于同样的原因,即使它们更加精确、正确和易于理解。如果您发现我的评论有需要改进的地方,请告诉我。感谢您的评论。 - darijan

-1

Integer在范围-128至+127内是预先创建的。您可以将这些视为位于“整数池”中。

任何其他值都是在运行时创建的。

这导致Java中的一些微妙行为:

对于两个Integerfoobar,表达式boo == far如果它们的值相等且位于-128至+127的范围内,则为true。对于超出该范围的值,它将不为true:您需要使用.equals来处理这些值。

就我个人而言,我觉得这种行为很有害:永远不要在包装类型上使用==


这对于 new Integer(20) 也适用吗?我认为这只适用于装箱。 - user23127
1
不,对于新的Integer(20),这是不正确的,因为它将始终创建一个新对象。这仅适用于自动装箱,因为它使用“valueOf”方法,其中使用预先创建的值。 - Florian Schaetz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接