我有以下代码:
Circle c1 = new Circle();
Circle c2 = new Circle();
System.out.println(c1 == c2);
正如预期的那样输出False
。这是因为c1
和c2
是引用类型,而“==”检查它们是否引用相同类型(它们不引用)。
但是,我最近尝试过这个:
String a = "hello";
String b = "hello";
System.out.println(a == b);
由于某种原因输出True
。为什么是这样? String是引用类型,a
和b
引用不同的内存位置。我总是被告知你需要使用.equals()
来实现这一点,但事实并非如此!
更新
这不是一个重复!
我知道比较字符串的正确方法是使用.eqauls()
更新2 这个问题可能有答案:How do I compare strings in Java?,但问题是没有问我在问什么,答案只是比需要的更详细。
因此,使用我的同一问题(在谷歌或其他方面)搜索意味着用户不会被发送到该问题,或者由于问题的标题可能会完全解雇。因此,为了其他用户的利益而保持这一点可能是一个好主意!
答案 0 :(得分:5)
因为字符串文字是实习的,所以相同的文字引用同一个对象。因此,检查它们之间的引用相等性必然会返回true。
来自Java语言规范(3.10.5):
此外,字符串文字始终引用类String的相同实例。这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被“实例化”以便使用String.intern方法共享唯一实例。
实际上,编译器将“早期”汇集字符串文字,并仅在已编译的.class文件中存储一个副本。但是,来自单独的类文件的相同字符串文字仍将使用==
进行比较,因为在加载类时文字仍然是实例化的。
另一方面,如果我们正确地将您的示例应用于Circle to String,我们将会:
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // will print false!
在这种情况下,我们显式创建新对象,因此它们不能是相等的引用。
通过文字或其他常量字符串表达式以外的方式构造的任何字符串也不一定与引用相等的字符串相同。例如:
String a = "hello";
String b = "hello";
System.out.println(a.substring(0,3) == b.substring(0,3)); // may print false!
答案 1 :(得分:2)
字符串实习。由于a
和b
都是具有相同值的常量,因此编译器利用String的不变性使两个变量都引用相同的字符串,从而节省空间。因此==
会返回True
,因为它们实际上是同一个对象。
答案 2 :(得分:1)
在这种情况下,"你好"被视为一个常数,分配给a和b。所以这里==实际上返回true。如果你这样做:
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b);
您将获得false
。