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

我理解等于运算符比较对字符串的引用。因此,它将检查字符串是否引用相同的对象,而不是它们是否逐个字符。

作为学习搜索算法的第一步,我设置了以下程序,其中有一个名称数组,然后检查数组中是否出现某个名称。

第一种方法

我声明并初始化名称数组。我要求用户输入一个名称来检查它是否出现在数组中。

这是我用过的代码 -

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);
            } 
        }
    }}

以下屏幕截图显示了此程序的其中一个运行 - 

https://img4.mukewang.com/5cdbf14b00015d1a07240147.jpg

正如预期的那样,因为我使用==运算符来比较字符串,所以即使它出现在初始数组中,也无法在数组中找到名称“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” - 

https://img4.mukewang.com/5cdbf14c0001b99907300055.jpg

有人可以解释这两种情况的区别吗?


繁花如伊
浏览 483回答 3
3回答

慕勒3428872

这是因为编译器重用了编译时已知的字符串文字中的字符串实例。因此,他们通过对象相等性检查。可以重用,因为字符串是不可变对象。在编译时不知道和/或显式创建为new String对象的字符串不受此优化的约束,并且始终会生成新对象。

繁星点点滴滴

只有两种情况==可以保证(按照您的意愿)进行字符串测试:您String明确创建了一个对象,并确保在两个不同的位置使用相同的引用。您肯定知道您正在比较的两个字符串都已被实习。注意到字符串文字总是1个实习。从技术上讲,实习字符串是String::intern在其生命周期中调用一段时间的结果。(参见JLS 3.10.5和javadoc。)非正式地,一个interned字符串是“在字符串池中”的字符串,尽管术语“字符串池”没有在任何地方指定2。任何其他事情==都有可能给出错误的答案。而且......这两种情况在现实世界的节目中很少出现。1 - 不严格100%为真:考虑在常量表达式中是子表达式的文字。但是,这不会影响==操作员的行为。2 - 我发现的最接近的是“一个字符串池,最初为空,由String&nbsp;javadocs中的类私有维护”。但是当前的javadocs,JLS和JVM规范不使用短语“字符串池”或“字符串常量池”或任何我能找到的地方的任何其他变体。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java