java equals()和 ‘==’,‘!=’的使用和易错点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java equals()和 ‘==’,‘!=’的使用和易错点相关的知识,希望对你有一定的参考价值。

 

 

        关系操作符==和!=使用于所有对象的比较,返回boolean值,这两个操作符常常会使第一次接触java的程序员感到迷惑。下面是一个例子           

public class EqualsTest {
public static void main(String[] args) {
Integer in1 = new Integer(100);
Integer in2 = new Integer(100);
System.out.println(in1==in2);
System.out.println(in1!=in2);
}
}

 

        语句System.out.println(n1==n2)将打印出括号内的比较式的布尔值结果。读者可能认为输出结果先是true,再是false,因为两个Integer对象都是相同的。但是尽管对象的内容相同,然而对象的引用(每new一个对象就是一个引用)却是不同的,而==和!=比较的就是对象的引用。所有输出结果实际先是false,再是true。其实这里主要是理解==这个操作关系符就够了。

  谈到 == 关系操作符我们肯定会想到equals()方法,再看下下面的例子:

public class EqualsTest {

public static void main(String[] args) {
Integer in1 = new Integer(100);
Integer in2 = new Integer(100);
System.out.println(in1.equals(in2));
}
}
这里输出的结果是true。问题来了,到这里我们是否能够得到这样的结论:

  ‘==’ 关系操作符比较的是对象的引用,而 equals() 比较的是对象的实际内容。

先别急着下结论,我们再看看下面的例子:public class EqualsTest {

public static void main(String[] args) {
Value v1 = new Value(100);
Value v2 = new Value(100);
System.out.println("v1.equals(v2)? "+v1.equals(v2));
}
}
class Value{
int i;
public Value(int i){
this.i = i;
}
}
出乎意料的这里的输出实际结果为false,这就让人难以理解了啊!说明上面的结论不正确了啊,这样的话这个equals()就有点坑爹了啊。为了搞清楚这个问题,下面我们来追踪下equals()这个方法。
  
首先我们得先明白这个equals是哪来的,由上面的代码我们可以看到Value这个对象压根就没有equals()方法,那么equals从哪里呢?
    如果在创建类的时候没有声明要继承的类,那么java就默认把它继承Object类。所以Object就是所有类的父类。

这样我们就明白了equals()来自Value类的父类Object,下面我们来看下Object的equals()这个方法:
  技术分享
从上面的代码可以看出Object的equals方法比较的是对象的引用而不是对象的实际内容,这时我们的一个疑问是:
    
    为什么Integer的equals()方法比较的是对象的实际内容?

为了解答这个问题,我们来看看Integer类的原码:
  技术分享
  技术分享
技术分享
技术分享
   通过上面四张截图我们就知道了,Integer已经覆盖了Object的equals()方法,使得Interger的equals()方法比较的是对象的实际内容值(int value)。
  
  现在我把Value也重写下equals()方法,代码如下:
public class EqualsTest {
    public static void main(String[] args) {
Value v1 = new Value(100);
Value v2 = new Value(100);
System.out.println(v1.equals(v2));
}
}
class Value{
int i;
public int getValue(){
return i;
}
public Value(){
}
public Value(int i){
this.i = i;
}
public boolean equals(Object obj){
if(obj instanceof Value){
return i ==((Value) obj).getValue();
}
return false;
}
}
  这时输出的结果就是我们想要的结果:true。
  
这时我们就可以得出结论:
      ‘==’ 关系操作符比较的是对象的引用,而Object类的equals()比较的也是对象的引用,如果想要比较对象的实际内容可以覆盖父类
(Object)的equals()方法,eg:java JDK 自带的类:Integer,String等。
  
  注:
    当Integer i的值在 [-128,128) 的范围内是,java就会把变量i当做一个变量,放到内存中;但如果不在这个范围内,就会去new一个Integer对象,
  所以当Ingeter值在 [-128,128)的范围内时,‘==’比较的是对象的实际内容值,既变量的值而不是比较引用。

这是本人的第一篇博客,写的不好,也可能有写得不对的地方,请各位读者能给出宝贵的意见,本人写博客是为了加深对一些东西印象和理解。

2017/8/23




  

 

 

 

 

 

























































































以上是关于java equals()和 ‘==’,‘!=’的使用和易错点的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中的equals()

提问一个java的问题:是有关equals()和==的,问题如下

java 集合中重写hashCode方法和重写equals方法啥关系?

关于java中equals方法的疑惑

java里 equals和== 区别

java中equals和equalsignorecase的区别