【问题标题】:Comparing two strings with equal(==) operator [duplicate]用相等(==)运算符比较两个字符串[重复]
【发布时间】:2013-09-01 04:55:12
【问题描述】:

我有点告诉某人,我们必须使用 String.equals 方法来比较两个字符串值,我们不能简单地在 java 中使用 == 运算符来比较字符串,并告诉他 == 将返回 false不比较字符串值,而是比较字符串对象引用值。

我写了这个例子给他看,但令我惊讶的是,它总是为 == 运算符打印 true.. 这是代码

public void exampleFunc1(){

    String string1 = "ABC";
    String string2 = "ABC";

    if(string1 == string2)
        System.out.println("true");
    else{
        System.out.println("false");

    }   
    System.out.println(" Are they equal "+(string1 == string2)); // this shouldn't print True but it does
    System.out.println(" Are they equal "+(string1.equals(string2)));

}

输出:-

它们是否相等

它们是否相等

所以这里的问题是,除了两个对象是同一个实例之外,对象上的 == 运算符在什么情况下可以打印 true?

【问题讨论】:

标签: java logic


【解决方案1】:

String 是少数特殊情况之一。

String 类保留了一个特殊的“实习”池Strings。方法myString.intern() 在此池中查找myString。如果池中已经存在另一个具有相同内容的String,则返回指向它的指针。如果不是,则添加myString(并返回一个指针)。

当您说myString= myString.intern() ; 时,您实际上是在使myString 引用共享副本或其底层String 可用于将来共享(并且没有重复)。大多数创建 Strings 的库方法都受此约束,尤其是 String 文字。

“实习”的其他情况发生在包装器类型 IntegerLong 等中。它们没有构造函数,但静态方法 valueOf() 可以返回预构建的共享对象(通常是256 个最接近零的值),以及新对象时不能。后者问题不大,因为这些类型比Strings 更轻量级。例如,Long 的有效负载只有 8 个字节。 String 包含一个 char[],即使是空的也是 16 个字节左右。

要回答您的问题,您不能指望任何“实习”机制。它们在过去发生了变化,并且将来可能会发生变化(甚至从一个 JVM 到另一个),从而使您的代码无法使用。始终使用equals

【讨论】:

  • 谢谢,如果我们改变一个字符串值会发生什么
  • @Ankit 怎么样?用串联?我的印象是串联实习结果。使用String 功能?一样。唯一的逃避是通过使用String 构造函数强制创建新的Strings。如果 Java 团队之前考虑过实习,那么这些就不会存在,并且类似于包装类型(没有构造函数,只是类似于构造函数的静态方法)。
  • 听起来不错,谢谢 :),快乐编码。
【解决方案2】:

你应该使用

String string1 = new String("ABC");

String string2 = new String("ABC");

那么一切都会如你所想的那样正确,

在这种情况下,“ABC”只是对 const 字符串的引用。

【讨论】:

  • @Ankit 那是因为new 强制创建一个新的String。构造函数不能返回与其正在构造的对象不同的对象。但是,如果您对两个字符串都进行了实习,您将返回string1 == string2
【解决方案3】:

编译器可能正在优化分配并且只创建一个 String 对象。如果您使用显式 String 构造函数,== 操作应该按预期运行。

【讨论】:

    猜你喜欢
    • 2011-04-25
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多