当前位置: 首页 > 知识库问答 >
问题:

使用字符串文本创建字符串常量池的编译器行为

白刚洁
2023-03-14

看完这些讨论——问题1,问题2,文章

我对Java字符串常量池有以下理解(如果我错了,请纠正我):

编译源代码时,编译器会在我们的程序中查找所有字符串文字(放在双引号中的那些),并在堆区域中创建不同的(无重复)对象,并在称为字符串常量池(方法区域内的区域)的特殊内存区域中维护它们的引用。任何其他字符串对象都是在运行时创建的。

假设我们的代码有以下语句:

String a = "abc";                  //Line 1
String b = "xyz";                  //Line 2
String c = "abc";                  //Line 3
String d = new String("abc"):      //Line 4

当编译上述代码时,

第1行:在堆中创建一个String对象“abc”,该对象由变量a和String常量池引用。

第2行:编译器在字符串常量池中搜索对对象“xyz”的任何现有引用。但找不到。因此,它创建对象“xyz”并将其引用放在字符串常量池中。

第3行:这一次编译器在字符串常量池中找到对象,并且不会在池或堆中创建任何其他条目。变量c只是指现有对象,它也被a引用。

第 4 行:第 4 行中的文字存在于字符串常量池中。因此,不会再在池中进行任何输入。但是,在运行时为“abc”创建另一个字符串对象,其引用存储在变量 d 中。

现在我有以下问题/疑问:

    < li >这就是上面描述的情况吗? < li >编译器如何创建对象?据我所知,对象是在运行时创建的,堆是运行时内存区域。那么,字符串对象在编译的时候是怎么创建的,在哪里创建的呢! < li >源代码可以在一台机器上编译,在另一台机器上运行。或者,即使在同一台机器上,它们也可以在不同的时间被编译和运行。那么那些对象(编译时创建的)是如何恢复的呢? < li >当我们对一个字符串进行整型时会发生什么。

共有1个答案

富锦
2023-03-14
  1. 这就是上面描述的事情吗?

是的,但是,从概念上讲,常量池和字符串池是不同的东西。

常量池是<code>的一部分。class</code>文件,其中包含该类中使用的所有常量。

字符串池是一个运行时概念——中间字符串和字符串文字存储在这里。

下面是关于常量池的JVM规范。它是<代码>一节的一部分。类格式。

我认为,这是如何/何时发生的,是JVM实现特定的细节(如果我错了,请纠正我),但基本的解释是,每当JVM决定加载一个类时,在常量池中找到的任何字符串都会自动放入运行时字符串池中,并且任何副本都会引用同一个实例

在其中一个链接答案的评论中,Pa lo Ebermann说:

当类被加载到VM中时,字符串常量将被复制到堆中,复制到VM范围的字符串池中

因此,这似乎至少是Sun的VM实现字符串池的方式。

在JDK7/HotSpot之前,内部字符串存储在永久生成空间中,现在它们存储在主堆中。

常量存储在已编译的文件中。因此,每当 JVM 决定加载此类时,它们都是可检索的。

答案如下:

对一系列字符串执行 String.intern() 将确保具有相同内容的所有字符串共享相同的内存

 类似资料:
  • 当使用关键字 new 创建字符串时,它使用采用 String 文本的构造函数创建新的 String 对象。我想知道在调用 String 构造函数之前,文本是否存储在常量池中。 我这么问的原因是,在《OCA Java SE 7程序员I认证指南》中,Mala Gupta写道: 她在第一行表示,new创建的String对象不会存储在常量池中。这很好,但不清楚的是,第一行构造函数中的字面“Summer”是

  • 如这些问题中所述:问题1 在以下情况下,JVM将创建一个新的字符串对象,而不是使用字符串池中的现有对象: 然而,在阅读了下面两个类似的陈述之后,我有一个疑问。 从SCJP准备书: 当编译器遇到字符串文字时,它会检查池中是否已经存在相同的字符串。如果找到匹配项,对新文本的引用将指向现有的String,并且不会创建新的String文本对象。 来自JavaRanch: 在本例中,由于关键字“new”,我

  • 我读到字符串常量池也是自引用的,在这个链接中,它被写为字符串文本的创建: 将在堆中创建一个新字符串“new”(如果没有)。那么,这是否意味着不管对象是文本对象还是使用new关键字的新对象,都会在堆中创建对象? 我对intern的理解是-它检查堆中是否有同名的对象,然后引用它,否则在堆中创建新对象。如果我错了,请纠正。 我还有一个疑问——常量池是包含对象,还是只包含对堆中对象的引用。

  • 我正在学习如何通过OCA考试,并坚持这个java字符串池的概念。 考虑以下几点: 和在字符串中是相同的,在对象中也是相同的,因为它是相同的字符串文本,所以JVM在编译时将字符串池和。 现在,是在运行时计算的,因此应该返回一个新字符串。因此,应该为false,但事实并非如此。为什么? 我的一个理论是方法首先检查是否有空白需要删除,如果没有,则简单返回本身。这可以解释为什么s1==s3,但我不确定。

  • 根据Java, 字符串存储在两个地方。字符串字面池和堆内存根据其创建。我需要知道,当字符串赋值到另一个字符串时,新创建的字符串将存储在哪里? 我对堆和字符串池中的字符串类型都进行了赋值操作。我得到了这样的结果。 但是当, 如果我这么做 同样地, 现在 以上是我在IDE上得到的输出。根据该输出,strNew的一个新引用对象在字符串池中创建,strNew的一个新引用对象在堆中创建。对吗?

  • 我的问题很简单。有什么区别-