4

昨天(2012 年 4 月 5 日)我正在尝试比较环境中的字符串:

电脑 1

  1. Java(TM) SE 运行时环境(构建 1.6.0_29-b11-402-11D50b)
  2. OS X 10.7.3

电脑 2

  1. Java(TM) SE 运行时环境(构建 1.6.0_29-b11-402-11D50b)
  2. 窗口 7

电脑 3

  1. Java(TM) SE 运行时环境(构建 1.6.0_29-b11-402-11D50b)
  2. Linux Ubuntu 11.10

这是我正在尝试的代码

public class TComp{
    public static void main(String[] args){
        String a = "arif";
        String b = "arif";
        if(a==b){
            System.out.println("match!");
        }
    }
}

据我所知,要在 java 中比较字符串,我们应该使用 .equal() 函数,而 '==' 将在这种情况下进行实习。但是对于那些所有具有不同操作系统的计算机,为什么实习生在计算机 1 上工作正常,而我在计算机 2 和计算机 3 上却出现错误?

如果我有任何错误,请纠正。谢谢你。

4

7 回答 7

5

在同一个类中,所有字符串常量都.class被编译器(在编译时)折叠到文件常量池中。这意味着编译器将只存储字符串的一份副本(因为谁需要在池中使用两个相同的常量?)。

这意味着在一个类中,==字符串的比较通常是有效的。然而,在你太兴奋之前,有一个很好的理由永远不要使用==字符串比较。 不能保证您比较的两个字符串都来自类内常量池。

所以,

"foo" == new String("foo")

完全有可能失败,而

"foo" == "foo"

可能会奏效。这可能在很大程度上取决于实现,如果您对实现而不是规范进行编码,那么如果实现发生更改,您可能会发现自己非常令人讨厌,因为规范实际上并不需要实现。

简而言之,每次都.equals(...)用于比较。Object==用于原始比较和“这是同一对象实例”比较。即使您认为这两者Strings可能被实习(或同一个对象),因为您永远不知道何时会在不同的类加载器下、在不同的 JVM 实现上或在决定不实习所有内容的机器上运行。

于 2012-04-05T00:21:10.357 回答
1

字符串实习完全取决于编译器。== 不会“实习”任何东西;它只是比较对象身份。在某些情况下,a 和 b 可以指向同一个对象。在其他情况下,他们不会。两者都是合法的,所以你确实应该使用 .equals()。

另请参见http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

于 2012-04-05T00:04:48.743 回答
1

这是因为每当您创建编译时常量字符串时,Java 都会执行String interning 。

JLS 15.28。常量表达式

使用 String.intern 方法,String 类型的编译时常量表达式始终是“内部”的,以便共享唯一的实例。

这就是为什么在使用“==”进行比较时会得到 true 的原因,因为它们实际上是同一个对象。 String.valueOf() 的工作方式与字符串常量相同。

String x = "a";
String y = "a";
System.out.println(x == y); // true


String w = new String("b");
String z = "b";
System.out.println(w == z); // false
于 2012-04-05T00:51:50.987 回答
1

在一台计算机上,它们是同一对象,而在另一台计算机上却不是。语言的规则没有指定它们是否是同一个对象,所以它可以以任何一种方式发生。

于 2012-04-05T00:04:05.640 回答
0

使用 == 来比较对象根本不可靠。除非你真的在寻找完全相同的实例,否则你永远不应该使用 == 来比较对象是否相等。

于 2012-04-05T00:05:10.917 回答
0

== 运算符确定两个对象引用是否指向同一个实例。

另一方面, .equals() 方法比较对象中的实际字符。

这些应该与您使用的计算机无关。

于 2012-04-05T00:06:15.360 回答
0

最好的办法是始终使用 .equals 来比较对象。但是对于 String 如果您出于某些奇怪的原因需要使用 == 运算符,则需要确保比较.intern 方法的结果。它总是返回实习值,并且文档告诉它是唯一的。医生说所有的 const 都是实习生的,也是独一无二的。

于 2012-04-05T00:42:47.420 回答