1、认识‘==’与Object类equals()方法
首先 ‘==’ 和equals我们都常常用过,但这两者的区别我们却不一定清楚,首先我们我们说下 '=='。
' == ' 号在比较基本数据类型时比较的是值,而用 ' == ' 号比较两个对象时比较的是两个对象的地址值
1 int a = 1 ;2 int b = 1 ;3 System.out.println( a == b);//true4 Object obj1 = new Object() ;5 Object obj2 = new Object() ;6 System.out.println( obj1 == obj2 );//false7 System.out.println( obj1.equals(obj2) );//false
第3行是基本类型比较,值相同所以是true 第6行是比较的是两个对象的地址,所以不相同,如果有人问第7行为什么是false,obj1和obj2值不是一样的吗?为什么是false呢?我们来看下Object类的equals源码就知道了。
1 // 这是Object类的equals方法2 public boolean equals(Object obj) {3 return (this == obj);4 }
通过看源码我们就知道为啥obj1.equals(obj2)是false了,因为Object equals的实现是用 ‘==’ 判断的。
2、认识String类中的equals()方法
我们接下来看下下面这段代码??可能你会发现点东西!!!
1 String str1 = "abc" ;2 String str2 = "abc" ;3 String str3 = new String("abc") ;4 System.out.println( str1 == str2 );//true5 System.out.println( str1 == str3 );//false6 System.out.println( str1.equals(str2) );//true7 System.out.println( str1.equals(str3) );//true
我们都知道内存中的常量池,常量池属于方法区的一部分,当运行到str1创建对象时,如果常量池中没有,就在常量池中创建一个对象”abc”,第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。所以第4行是true 第三行中的String str3 = new String("abc")创建了两次对象,依次是在常量池中创建了对象”abc”,一次是在堆内存中创建了对象str3,所以str1和str3的地址值不相等。
对于第6 7行为什么都是true呢?这就追究于String重写了Object类的equals方法,我们看下源码
1 //这是String类的equals方法 2 public boolean equals(Object anObject) { 3 if (this == anObject) { 4 return true; 5 } 6 if (anObject instanceof String) { 7 String anotherString = (String)anObject; 8 int n = value.length; 9 if (n == anotherString.value.length) {10 char v1[] = value;11 char v2[] = anotherString.value;12 int i = 0;13 while (n-- != 0) {14 if (v1[i] != v2[i])15 return false;16 i++;17 }18 return true;19 }20 }21 return false;22 }
我们能看出,首先我们判断这两个地址是不是一样的,如果是一样的,直接返回true,如果不一样再判断传进来的参数是不是String类型,如果是,那么我们就将这两个Stirng拆分成数组,一一比较这两个数组之中的值。如果这两个数组元素都相等,那么就是true,所以在上面str1.equals("str2")和str1.equals("str3")都是true。