字符串常量池 [英] String Constant Pool

查看:105
本文介绍了字符串常量池的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如这些Stackoverflow问题中所述:问题1 & 问题2 我理解字符串文字是< a href =http://en.wikipedia.org/wiki/String_interning =noreferrer>实习时:

As explained in these Stackoverflow questions: question 1 & question 2 I understand that "String literals" are interned when:

String s = "abc"; 

并且JVM将创建一个新的String对象,而不是使用字符串池中的现有对象。 :

And that the JVM will create a new String object instead of using an existing one from the String Pool when:

String s = new String("abc");

但是,在阅读以下两个类似的陈述后,我有一个疑问。

However, I have a doubt after reading the following two similar statements.

  • From SCJP preparation book:

当编译器遇到字符串文字时,它检查池以查看是否已存在相同的String。如果找到匹配项,则对新文本的引用将定向到现有String,并且不会创建新的String文本对象。




  • 来自 JavaRanch:

    • From JavaRanch:

    • 在这种情况下,由于关键字,我们实际上会遇到略微不同的行为新。在这种情况下,对字符串文字的引用仍然放在常量表(String Literal Pool)中,但是,当你来到关键字new时,JVM必须在运行时创建一个新的String对象,而不是使用常量表中的那个。

      因此,如果我们也在非池内存中添加引用当我们使用new并基于上面的定义创建对象时,在池内存中当我们这样做时,JVM是否也应该返回相同的引用?

      So if we also put a reference in nonpool memory AND in pool memory when we create an object using "new" and based on the definitions above. Shouldn't the JVM also return the same reference when we do this?:

      String one = new String("test");
      String two = "test";
      
      System.out.println(one.equals(two)); // true
      System.out.println(one == two);      // false
      

      因为声明字符串文字时字符串三=测试 ; 它已经存在于池中了?因此应该返回相同的参考和打印真实?或者之前的陈述是否意味着它们将被放入池内存中,但只是在使用 new 运算符时跳过?

      Because when declaring the String literal String three = "test"; it will already exist in the pool? and therefore should return the same reference and print true? or do the previous statements mean that they will be put in pool memory but simply skipped when the new operator is used?

      推荐答案

      这可能有助于您的理解:

      Maybe this will aid your understanding:

      String literal = "test";
      String one = new String(literal);
      String two = "test";
      
      System.out.println(literal == two); //true
      System.out.println(one == two); //false
      

      在您发布的示例中:

      String one = new String("test");
      String two = "test";
      

      传递给构造函数的引用 String(String)与参考两个具有相同的值。但是,字符串本身(由这两个引用引用)用于构造 new 对象,该对象被分配给引用 one

      the reference passed to the constructor String(String) has the same value as the reference two due to interning. However, the string itself (referenced by these two references) is used to construct a new object which is assigned to reference one.

      在这个例子中,正好有两个 String 用值test创建:保持在每当在表达式中使用文字test时引用常量池并引用,第二个由new运算符创建并分配给引用一个

      In this example, there are exactly two Strings created with the value "test": the one maintained in the constant pool and referenced whenever you use the literal "test" in an expression, and the second one created by the "new" operator and assigned to the reference one.

      也许你对这个陈述感到困惑:

      Perhaps you're confused about this statement:


      当编译器遇到字符串文字时,它会检查池以查看是否已存在相同的字符串。

      When the compiler encounters a String literal, it checks the pool to see if an identical String already exists.

      请注意,这可能更清楚地表述为:

      Note that this might be more clearly stated as:


      编译器遇到字符串文字,它会检查池中是否存在相同的字符串

      字符串只有在明确地实现或通过类使用文字时才放入池中。例如,如果您有这种情况:

      Strings are only put in the pool when they are interned explicitly or by the class's use of a literal. So if you have, for example, this scenario:

      String te = "te";
      String st = "st";
      
      String test = new String(te) + new String(st);
      

      然后 String 存在,其值为 test ,表示字符串不会存在在池中作为文字test 从未发生过。

      then while a String will exist with the value test, said String will not exist in the pool as the literal "test" has never occurred.

      这篇关于字符串常量池的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆