字符串池在Java中为同一字符串创建两个字符串对象

字符串池在Java中为同一字符串创建两个字符串对象,java,string,Java,String,可能重复: 我创建了两个字符串 String s1="MyString"; String s2=new String("MyString"); System.out.println(s1==s2); 它会打印“false”。我们知道字符串池不会为同一个字符串文本创建两个对象 那么这里发生了什么?它在字符串池中为同一字符串文本“MyString”创建两个不同的字符串对象(文本) 我知道equals()方法在这里返回true 但是当我们使用==时,它应该比较两个引用,它们应该引用相同的引用 字符

可能重复:

我创建了两个字符串

String s1="MyString";
String s2=new String("MyString");
System.out.println(s1==s2);
它会打印
“false”
。我们知道字符串池不会为同一个字符串文本创建两个对象

那么这里发生了什么?它在字符串池中为同一字符串文本“MyString”创建两个不同的字符串对象(文本)

我知道
equals()
方法在这里返回
true

但是当我们使用
==
时,它应该比较两个引用,它们应该引用相同的引用 字符串常量池中的字符串对象


为什么即使找到匹配项也不引用字符串池中的现有字符串对象

行中的
String s2=新字符串(“MyString”)
您正在创建
字符串的新的实例,因此它肯定不会是与
s1
相同的实例

如果您这样做:

System.out.println(s1=="MyString");

您将得到
true

s2
不是字符串文字,它是在使用
new
时从一个字符串文字构造而来的-但它不是文字,它是一个新对象。

第一个字符串文字进入池,而第二个字符串文字存储在堆上

使用
s2=s2.intern()
使其返回
true

当您对字符串执行
intern()
操作时,JVM确保该字符串存在于池中。如果它还不存在,则在池中创建它。否则,将返回已经存在的实例。我认为这解释了
=
的行为

String s1="MyString";
String s2=new String("MyString");
s2 = s2.intern();
System.out.println(s1==s2);
作为参考,以下是
String.intern()
文档中的内容:

/**
 * Returns a canonical representation for the string object.
 * <p>
 * A pool of strings, initially empty, is maintained privately by the
 * class <code>String</code>.
 * <p>
 * When the intern method is invoked, if the pool already contains a
 * string equal to this <code>String</code> object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this <code>String</code> object is added to the
 * pool and a reference to this <code>String</code> object is returned.
 * <p>
 * It follows that for any two strings <code>s</code> and <code>t</code>,
 * <code>s.intern()&nbsp;==&nbsp;t.intern()</code> is <code>true</code>
 * if and only if <code>s.equals(t)</code> is <code>true</code>.
 * <p>
 * All literal strings and string-valued constant expressions are
 * interned. String literals are defined in section 3.10.5 of the
 * <cite>The Java&trade; Language Specification</cite>.
 *
 * @return  a string that has the same contents as this string, but is
 *          guaranteed to be from a pool of unique strings.
 */
public native String intern();

实际上,您正在创建两个不同的对象,一个在
文本池中,另一个在
堆中

String s1 = "MyString"; //literal pool
String s2 = new String("MyString"); //in heap
s.o.p(s1==s2); // false, because two different instances
s.o.p(s1.equals(s2)); // true, compares the contents of the string.
您需要使用
equals
代替
=

您可以通过调用
string.intern()
将字符串对象从堆推送到字符串文本池(或常量池)。字符串池并没有创建两个实例,而是构造函数调用创建了第二个
string
实例。从以下文件的javadoc:

初始化新创建的字符串对象,使其表示与参数相同的字符序列;换句话说,新创建的字符串是参数字符串的副本。除非需要原始的显式副本,否则不需要使用此构造函数,因为字符串是不可变的


因此,由于您正在创建第二个实例
==
正确地返回
false
(并将返回
true
)。

您正在比较明显不同的对象引用(指针)。使用字符串的
equal()
方法检查对象的相等性。是!那么你的问题到底是什么?@我不太了解equal()的用法,但我说的是“==”如果你使用
new
,Java总是会创建一个新对象。你为什么感到惊讶?我知道使用相等的值会匹配