判断对象的等价性

2018-06-11 16:52:47

对象等价性的判断

  • 如下一个简单的小栗子
 1 /**
 2  * 
 3  * @author Accper
 4  *
 5  */
 6 public class Equivalence {
 7     public static void main(String[] args) {
 8         Integer n1 = new Integer(50);
 9         Integer n2 = new Integer(50);
10         System.out.println(n1 == n2);
11         System.out.println(n1 != n2);
12     }    
13 }
  • 运行的结果为:false true。很多人第一反应肯定是一脸懵逼,别看程序短其实要追究起来,还是可以挖的很深,首先明确一点的是,"=="和"!="判断的是对象的引用;其次,两次new Integer(50),在堆储存空间中分配了两个内存空间,每个内存空间都有一个地址,对象的引用就是指向这个地址,所以两次new的对象的地址是不同的。

 

  • 如果上面的程序懂的话,但是有的人会问,我就是想比较它们的值,你能把我咋地。好吧,我们接着进行,快看下面的栗子
 1 /**
 2  * 
 3  * @author Accper
 4  *
 5  */
 6 public class EqualsMethod {
 7     public static void main(String[] args) {
 8         Integer n1 = new Integer(50);
 9         Integer n2 = new Integer(50);
10         System.out.println(n1.equals(n2));
11     }
12 }
  • 没错真如与其所想那样子,运行的结果为:true。注意一点的是,此方法不适用于"基本类型",基本类型是可以直接使用==和!=的。

 

  • 为了验证上面所学,我们再来一个栗子,看下面代码
 1 /**
 2  * 
 3  * @author Accper
 4  *
 5  */
 6 class Value {
 7     int i;
 8 }
 9 
10 public class EqualsMethod2 {
11     public static void main(String[] args) {
12         Value v1 = new Value();
13         Value v2 = new Value();
14         v1.i = v2.i = 99;
15         System.out.println(v1.equals(v2));
16     }
17 }
  • 没错,what is the fuck!运行结果是false。想知道为什么请看下面如何分析。

分析

  • 首先,请看Integer类中equals的源码,现在知道为什么上面的"n1.equals(n2)"结果为true了,因为Integer中的equals的确实是对其中的值进行比较的,不是引用。
 1     /**
 2      * Compares this object to the specified object.  The result is
 3      * {@code true} if and only if the argument is not
 4      * {@code null} and is an {@code Integer} object that
 5      * contains the same {@code int} value as this object.
 6      *
 7      * @param   obj   the object to compare with.
 8      * @return  {@code true} if the objects are the same;
 9      *          {@code false} otherwise.
10      */
11     public boolean equals(Object obj) {
12         if (obj instanceof Integer) {
13             return value == ((Integer)obj).intValue();
14         }
15         return false;
16     }
  • 那有的人会问,那为什么"v1.equals(v2)"的结果为false呢?我们知道所有类的祖宗都是Object类,而Value类中没有对equals方法进行重写,所以我们来看Object中equals方法的源码。因为Value类中直接使用的是Object类中的equals方法,所以还是判断的是对象的引用,不是其中的值。
 1      /**
 2      * Note that it is generally necessary to override the {@code hashCode}
 3      * method whenever this method is overridden, so as to maintain the
 4      * general contract for the {@code hashCode} method, which states
 5      * that equal objects must have equal hash codes.
 6      *
 7      * @param   obj   the reference object with which to compare.
 8      * @return  {@code true} if this object is the same as the obj
 9      *          argument; {@code false} otherwise.
10      * @see     #hashCode()
11      * @see     java.util.HashMap
12      */
13     public boolean equals(Object obj) {
14         return (this == obj);
15     }

总结

  • 还是源码大法好,没事的时候还是多研究研究源码,方知为什么。
posted @ 2018-06-11 17:59  Accper  阅读(331)  评论(0编辑  收藏  举报