为了账号安全,请及时绑定邮箱和手机立即绑定

“==”运算符何时成功比较字符串?[重复]

“==”运算符何时成功比较字符串?[重复]

繁花如伊 2019-04-18 23:19:42
我理解等于运算符比较对字符串的引用。因此,它将检查字符串是否引用相同的对象,而不是它们是否逐个字符。作为学习搜索算法的第一步,我设置了以下程序,其中有一个名称数组,然后检查数组中是否出现某个名称。第一种方法:我声明并初始化名称数组。我要求用户输入一个名称来检查它是否出现在数组中。这是我用过的代码 -import java.util.Scanner;public class Strawman{     public static void main(String[] args){         System.out.println("Enter the name to search for:");         Scanner scanner = new Scanner(System.in);         String key = scanner.nextLine();         String[] names = {"alice", "bob", "carlos", "carol", "craig", "dave", "erin", "eve", "frank", "mallory", "oscar", "peggy",          "trent", "walter", "wendy"};         for (int i = 0; i < names.length; i++){             if (key == names[i]) {                 System.out.println("Index " + i + " has the name " + key);             }          }     }}以下屏幕截图显示了此程序的其中一个运行 - 正如预期的那样,因为我使用==运算符来比较字符串,所以即使它出现在初始数组中,也无法在数组中找到名称“oscar”。根据我对等于运算符如何比较字符串引用的理解,此输出是预期的。但是,我不明白为什么程序似乎工作,如果不是要求用户输入,我声明要搜索为字符串的名称。第二种方法:要搜索的名称“oscar”已声明为字符串,而不是要求用户输入 -public class Strawman2{     public static void main(String[] args){         String[] names = {"alice", "bob", "carol", "craig", "carlos", "dave", "eve", "fred", "greg", "gregory", "oscar", "peter"};         String key = "oscar";         for (int i = 0; i < names.length; i++){             if (names[i] == key){                 System.out.println("Index " + i + " has name " + key);             }         }     }}现在,如果我运行程序,在阵列中找到名称“oscar” - 有人可以解释这两种情况的区别吗?
查看完整描述

3 回答

?
慕勒3428872

TA贡献1848条经验 获得超6个赞

这是因为编译器重用了编译时已知的字符串文字中的字符串实例。因此,他们通过对象相等性检查。可以重用,因为字符串是不可变对象。

在编译时不知道和/或显式创建为new String对象的字符串不受此优化的约束,并且始终会生成新对象。


查看完整回答
反对 回复 2019-05-15
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

只有两种情况==可以保证(按照您的意愿)进行字符串测试:

  1. String明确创建了一个对象,并确保在两个不同的位置使用相同的引用。

  2. 您肯定知道您正在比较的两个字符串都已被实习。注意到字符串文字总是1个实习。

    从技术上讲,实习字符串是String::intern在其生命周期中调用一段时间的结果。(参见JLS 3.10.5javadoc。)非正式地,一个interned字符串是“在字符串池中”的字符串,尽管术语“字符串池”没有在任何地方指定2

任何其他事情==都有可能给出错误的答案。

而且......这两种情况在现实世界的节目中很少出现。


1 - 不严格100%为真:考虑在常量表达式中是子表达式的文字。但是,这不会影响==操作员的行为。

2 - 我发现的最接近的是“一个字符串池,最初为空,由String javadocs中的类私有维护。但是当前的javadocs,JLS和JVM规范不使用短语“字符串池”“字符串常量池”或任何我能找到的地方的任何其他变体。


查看完整回答
反对 回复 2019-05-15
  • 3 回答
  • 0 关注
  • 482 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号