我了解到,使用==
而不是String.equals()
来测试字符串相等是因为每个String都是对自己对象的引用。
但如果我使用像
这样的东西System.out.println("Hello" == "Hello");
它打印为真。
为什么?
答案 0 :(得分:26)
没有。这仍然是一件坏事 - 你仍然会测试引用相等而不是值相等。
public class Test
{
public static void main(String[] args)
{
String x = "hello";
String y = new String(x);
System.out.println(x == y); // Prints false
}
}
如果您现在看到==测试“工作”,那么这是因为您真正拥有相同的参考。看到这个的最常见原因可能是由于字符串文字的实习,但这是永远在Java中的:
public class Test
{
public static void main(String[] args)
{
String x = "hello";
String y = "hel" + "lo"; // Concatenated at compile-time
System.out.println(x == y); // Prints true
}
}
这由Java语言规范的section 3.10.5保证:
每个字符串文字都是一个参考 (§4.3)实例(§4.3.1,§12.5) String类(第4.3.3节)。串 对象具有常量值。串 文字 - 或者更一般地说,字符串 这是常数的值 表达式(§15.28) - 实际上是“实习” 至于共享唯一的实例,使用 方法String.intern。
答案 1 :(得分:3)
它没有改变。但是,Java编译器使用string.intern()来确保源代码中的相同字符串编译为相同的String对象。但是,如果从文件或数据库加载String,它将不是同一个对象,除非使用String.intern()或其他方法强制执行此操作。
这是一个坏主意,你仍然应该使用.equals()
答案 2 :(得分:1)
看,这是一个棘手的概念。
之间有区别:
// These are String literals
String a = "Hiabc";
String b = "abc";
String c = "abc";
和
// These are String objects.
String a = new String("Hiabc");
String b = new String("abc");
String c = new String("abc");
如果您的字符串是对象,即
String b = new String("abc");
String c = new String("abc");
然后,在两个不同的内存位置的String池中创建两个不同的对象并执行
b == c
会产生false
。
但由于您的String b
和String c
是文字,
b == c
结果true
。这是因为没有创建两个不同的对象。并且a
和b
都指向堆栈内存中的相同String。
这是不同的。你是对的,==
比较内存位置。这就是原因,
a.substring(2, 5) == b; // a,substring(2, 5) = "abc" which is at the location of b, and
b == c // will be true, coz both b and c are literals. And their values are compared and not memory locations.
为了让两个单独的字符串具有相同的值但位于String pool
和 NOT stack memory
的不同位置,您需要创建如上所示的String对象。
所以,
a.substring(2, 5) == b; // and
b == c; // will be false. as not both are objects. Hence are stored on separate memory locations on the String pool.
你必须使用
a.substring(2, 5).equals(b);
b.equals(c);
如果是对象。