Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 等同法混淆_Java_Equals - Fatal编程技术网

Java 等同法混淆

Java 等同法混淆,java,equals,Java,Equals,每当我对两个不同的StringBuffer对象使用equals()方法时,我得到的结果是false,但当我对两个不同的String对象使用equals()方法时,我得到的结果是true。为什么? String s=new String("434"); String s1=new String("434"); System.out.println(s.equals(s1));//true StringBuffer s=new StringBuffer("434")

每当我对两个不同的StringBuffer对象使用equals()方法时,我得到的结果是false,但当我对两个不同的String对象使用equals()方法时,我得到的结果是true。为什么?

    String s=new String("434");
    String s1=new String("434");

    System.out.println(s.equals(s1));//true

   StringBuffer s=new StringBuffer("434");
   StringBuffer s1=new StringBuffer("434");

   System.out.println(s.equals(s1));//false

StringBuffer不重写equals()。因此,调用Object.equals(),比较对象标识(内存地址)。String会覆盖equals并比较内容。

String s.equals将使用String表来比较实际字符串,其中作为StringBuffer sb.equals将只使用equals方法的默认实现并只比较对象指针。

至少在我的JDK版本(Sun 1.6)中,StringBuffer未实现equals()方法。这意味着它继承了对象的equals()方法,该方法与==


如果您确实想测试两个StringBuffers是否相等,可以调用x.toString().equals(y.toString())

StringBuffer
不会覆盖
对象#equals()
,因此您正在经历基于引用标识的检查,而不是基于值的检查。由于这些
StringBuilder
实例是不同的,每个实例具有不同的内存位置,因此基本
对象#equals()
实现将始终返回false

以下是Java 6的定义:

public boolean equals(Object obj) {
  return (this == obj);
}

看到问题了吗?

如果您要做的是比较两个StringBuffer对象的字符串表示形式,那么您要做的是:

StringBuffer sb1 = new StringBuffer("434");
StringBuffer sb2 = new StringBuffer("434");
if (sb1.toString().equals(sb2.toString())) {
  // whatever you want to do if they're equal
} else {
  // whatever you want to do if they're not
}

否则,您将比较两个StringBuffer对象的相等性,而不是它们的内容——换句话说,执行对象#equals(),而不是(不存在的)StringBuffer#equals()。

equals仅在两个对象相同时才在StringBuffer对象上返回true。要按所需方式比较StringBuffers,请使用以下命令:

System.out.println(s.toString().equals(s1.toString());

StringBuffer没有自己的equals方法实现,它从对象类继承equals()方法,因此比较哈希值,而不是比较StringBuffer中的实际内容。因此,我们必须显式地将其转换为一个string对象,该对象提供equals()方法的实现。

string对象的语义是这样的,如果观察到两个实例包含相同的字符序列,它们将始终包含相同的字符序列,并且可以(至少从
字符串
对象本身的角度来看)将对其中一个字符串的所有引用替换为对另一个字符串的引用,而不改变程序语义。这样的实例可能被认为是等效的,因为出于所有实际目的,
String
实例中封装的唯一信息是目标实例中包含的字符序列


相比之下,类型为
StringBuffer
的变量不仅封装了字符序列,还封装了特定实例的标识。如果两个变量引用同一个实例,更改为一个变量引用的实例将影响另一个变量引用的实例(因为它是同一个实例)。如果它们引用不同的实例,对其中一个引用的实例所做的更改将不会影响另一个引用的实例。决定不使用Java的
StringBuffer
override
equals
不是懒惰的结果,而是基于
StringBuffer
对象有一个有意义的标识,不相交的实例总是有不同的标识,如何在比较实际对象的字符串中使用equals的默认实现?使用
=
操作符来比较对象引用的相等性。是否有任何特定的原因StringBuffer.equals()方法未实现?可能是因为StringBuffer的实现可能会在不调用toString()的情况下使equals比较变得非常重要,因此最好通过强制客户端调用toString()来执行相等检查,从而使调用toString()的成本显式化。请注意,对
StringBuffer#toString()的每个调用
创建基础字符数组的新副本。如果您以后需要以
String
s的形式访问任何一个缓冲区,最好保存对
toString()
的第一次调用中的引用并重用它们。在整个对话中。。。我只能理解你的回答。