Java 在JDK1.6中,可以用==?

Java 在JDK1.6中,可以用==?,java,string,equals,Java,String,Equals,当我研究一些开源产品的源代码时,我发现如下代码: if (a=="cluser") a是一个字符串变量。字符串equals操作是否可以替换为=?仅当字符串已“插入”时。通常不会。运算符检查两个对象是否完全相同。它不会比较字符串中的内容。如果这两个字符串被插入,则可以使用==。字符串文本被定义为interned,因此,如果我将文本“fred”赋给字符串变量,并将其作为参数传递给另一个类中的方法,在该类中它与“fred”进行比较,则==测试将为true 因此样本代码不一定有缺陷,只是可能有缺陷。您

当我研究一些开源产品的源代码时,我发现如下代码:

if (a=="cluser")

a
是一个字符串变量。字符串
equals
操作是否可以替换为
=

仅当字符串已“插入”时。通常不会。

运算符检查两个对象是否完全相同。它不会比较字符串中的内容。

如果这两个字符串被插入,则可以使用==。字符串文本被定义为interned,因此,如果我将文本“fred”赋给字符串变量,并将其作为参数传递给另一个类中的方法,在该类中它与“fred”进行比较,则==测试将为true


因此样本代码不一定有缺陷,只是可能有缺陷。

您应该几乎永远不要使用
=
,并且几乎始终使用
equals()
。只有当两个字符串引用同一个对象时,它才适用于
=
String
上有一个
intern()
方法,可以为给定的字符串值返回相同的引用。字符串文本是隐式插入的。只有当您有很好的理由时,才应该使用
=
进行字符串比较,即使这样,您也需要非常小心


唯一好的理由是表现,而这很少有什么关系。只优化一次您肯定知道需要这样做。否则通常不值得这么麻烦。如果您正在查看一些开放源代码,它们可能有这样一种情况,即比较处于一个非常紧密的循环中,或者调用非常频繁,优化可以有所帮助。或者它只是过早地进行了优化,可能看起来是安全的。

来自Java语言规范,第3.10.5节字符串文本

每个字符串文字都是对类字符串实例的引用。字符串对象具有常量值。字符串文本,或者更一般地说,作为常量表达式值的字符串被“插入”,以便使用String.intern方法共享唯一实例

因此,由编译单元组成的测试程序:

package testPackage;
class Test {
        public static void main(String[] args) {
                String hello = "Hello", lo = "lo";
                System.out.print((hello == "Hello") + " ");
                System.out.print((Other.hello == hello) + " ");
                System.out.print((other.Other.hello == hello) + " ");
                System.out.print((hello == ("Hel"+"lo")) + " ");
                System.out.print((hello == ("Hel"+lo)) + " ");
                System.out.println(hello == ("Hel"+lo).intern());
        }
}
class Other { static String hello = "Hello"; }
package other;

public class Other { static String hello = "Hello"; }
及编制组:

package testPackage;
class Test {
        public static void main(String[] args) {
                String hello = "Hello", lo = "lo";
                System.out.print((hello == "Hello") + " ");
                System.out.print((Other.hello == hello) + " ");
                System.out.print((other.Other.hello == hello) + " ");
                System.out.print((hello == ("Hel"+"lo")) + " ");
                System.out.print((hello == ("Hel"+lo)) + " ");
                System.out.println(hello == ("Hel"+lo).intern());
        }
}
class Other { static String hello = "Hello"; }
package other;

public class Other { static String hello = "Hello"; }
生成输出:

true true true true false true
这个例子说明了六点:

  • 同一字符串中的文字字符串 同一包中的类表示 对同一字符串的引用 反对
  • 不同字符串中的文字字符串 同一包中的类 表示对相同对象的引用 字符串对象
  • 不同字符串中的文字字符串 不同包中的类 同样,表示对 相同的字符串对象
  • 由常量计算的字符串 表达式在编译时计算 时间,然后像对待他们一样对待他们 是文字
  • 通过在处串联计算的字符串 运行时是新创建的,并且 因此不同
  • 显式实习的结果 计算字符串是相同的字符串 作为任何预先存在的文本字符串 内容相同

  • 否,
    ==
    仍然表示对象引用相等。如果您正在阅读的代码试图进行字符串比较,则该代码是不正确的。通常,第三方代码基于正在插入的字符串,例如lucene或一些xml解析器。如果是这样的话,那么就可以使用==了。”…我发现代码像…-是的。很多产品都有缺陷。。。开源和闭源代码。我们中的一些人喜欢炫耀我们是多么聪明的bug,并在安全的情况下使用==作为字符串。这是一个性格缺陷,但你能做些什么呢?“也许如此”——这一点再强调也不为过!