Java 两个字符串及其引用的比较

Java 两个字符串及其引用的比较,java,string,object,Java,String,Object,一方面, String first = "thing"; String second = "thing"; if(first == second) System.out.print( "Same things" ); //this is printed 另一方面, String first = "thing"; String second = new String("thing"); if(first == second) { System.out.print("Same t

一方面,

String first = "thing";

String second = "thing";

if(first == second)

System.out.print( "Same things" );    //this is printed
另一方面,

String first = "thing";

String second = new String("thing");

if(first == second)
{
 System.out.print("Same things");
}
else
{
 System.out.print("Different things"); //This is printed
}

我知道“==”运算符用于比较两个对象的引用,但在第一个示例中,我直接比较了对象的值。我知道这种比较是不准确的。但为什么我在第一个例子中得到了这个信息?这是指引用相同,还是巧合?

我认为这就是Java通过缓存使用此方法创建的字符串进行优化的方式:

String second = "thing";
从而使他们“平等”

执行此操作时:

String second = new String("thing");

您显式地为这些内容分配一个新字符串,这会使您的
if
条件为false。

在第一个示例中,使用了
字符串池
,如果您不使用
new
关键字,则字符串的每个新实例都会到达该池,若创建了具有相同值的字符串—并没有创建新对象—那个么将使用池中的那个字符串

String first = "thing";

String second = new String("thing");

if(first.equals(second))
{
 System.out.print("Same things");
}
else
{
 System.out.print("Different things"); //This is printed
}

这应该是可行的。

在第一个示例中,Java将完全相同的对象分配给第一个和第二个

在第二个示例中,Java正在创建一个新对象“second”(内部指向第一个)。所以您有两个字符串对象,第一个和第二个,但第二个在内部包含对第一个的引用

有关详细信息,请参阅文档。由此:

返回字符串对象的规范表示形式。一滩 字符串最初为空,由类字符串私下维护

调用intern方法时,如果池已包含 字符串等于由equals(对象)确定的此字符串对象 方法,则返回池中的字符串。否则,这个 字符串对象被添加到池中,并引用此字符串 对象返回

因此,对于任意两个字符串s和t,s.intern()==t.intern() 当且仅当s.equals(t)为真时为真

所有文字字符串和字符串值常量表达式都是 实习。字符串文字定义见本手册§3.10.5


在第一个中,
first
second
具有相同的引用

但在第二种情况下,它们有不同的引用

使用
=
实际上是比较变量
first
second
中的值,这是对字符串对象的引用。您不是在比较对象本身。这将使用
equals
方法来完成。

字符串文本是您也可以使用

String first = "thing";

String second = new String("thing");

if(first.intern() == second.intern())
{
 System.out.print("Same things"); //This is printed
}
else
{
 System.out.print("Different things");
}

为什么会让人困惑?在第一个示例中,
first
second
都指向
“thing”
,这显然是同一个字符串。在第二个示例中,
second
指向一个新的
String
对象,该对象包含文本
“thing”
。当使用
==
时,不考虑
字符串的内容,因此两个
字符串
都包含文本
“thing”
这一事实是不相关的。可能存在相同字符串的重复,但尽管创建了不同的对象,但返回true。但参考文献应该有所不同。这就是为什么我混淆了它不是编译器,它的java优化实际上我不在乎equals()方法,它必须被使用。感谢您的关注。@El3ctr0n1c4:“但在第一个示例中,我直接比较了对象的值”,听起来像是您在比较那里对象的内容。所以,我只是想通过使用
==
确保您知道,您是在比较变量
第一个
第二个
的内容,而不是它们所指对象的内容。您是对的,我在那个地方错了。我试着提高我的英语:)小补充:如果你使用新的关键字-普通对象被创建并保存在堆上其他对象的位置。