码迷,mamicode.com
首页 > 编程语言 > 详细

Java中==和equals区别详解

时间:2015-05-04 15:38:45      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:java   比较   

首先来说下两种比较符的使用场景:
1、==是一般用来比较值类型,比较两个数据类型的值是否相等,例如:byte,shot,char,int,long,float,double,boolean,值类型(还有对象引用)一般存储在内存的栈中
2、equals用来比较复合数据类型,复合数据类型的变量在栈中存储的是引用类型变量的地址,本身存储在堆中。
当使用==比较复合数据类型时,比较的是他们在内存中的地址,使用同一个new出来的是相等,否则不相等。
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
每new一个Object他们的内存地址不相同。
下面先贴一下String的equals的源码看下:

/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

Object下即未被重写过的equals方法:

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

比较实质:
在JAVA中利用”==”比较变量时,系统使用变量在”栈”中所存的值作为比较的依据。
基本数据类型在”栈”中存的是其内容值,而对象类型在”栈”中存的是地址,这些地址指向”堆”中的对象。
java.lang包中的Object类有public boolean equals(Object obj)方法,它比较两个对象(hashcode)是否相等。
其它对象的equals方法仅当被比较的两个引用指向的对象内容相同时,对象的equals()方法返回true。
总之,”==”和”!=”比较的是地址.也可认为”==”和”!=”比较的是对象句柄;而equals()比较的是对象内容.或者说,,”==”和”!=”比较的是”栈”中的内容,而equals()比较的是”堆”中的内容.

publicclass Test{
publicstaticvoid main(String[] args) {
    String s1 ="null";
    String s2 =new String("null");
    System.out.println(s1==s2);//false
    s2 = s2.intern();
    System.out.println(s1==s2);//true
}

(java.lang.String的intern()方法”abc”.intern()方法的返回值还是字符串”abc”,表面上看起来好像这个方 法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在”abc”这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把”abc”添加到字符串池中,然后再返回它的引用。
下面来看一个特殊的比较:

 Integer i1 = 127;
  Integer j1 = 127;
  System.out.println(i1 == j1); // true

  Integer i2 = 128;
  Integer j2 = 128;
  System.out.println(i2 == j2);// false

以上是靠整型数的自动拆装箱实现的,而两者的结果却不相同。
原因在于,在进行自动拆装箱时,编译器会使用Integer.valueof()来创建Integer实例。
先看一下源码:

 public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

如果传入的int在IntegerCache.low和IntegerCache.high之间,那就尝试看前面的缓存中有没有打过包的相同的值,如果有就直接返回,否则就创建一个Integer实例。IntegerCache.low 默认是-128;IntegerCache.high默认是127.
注:如果要比较两个对象的内容是否相同,尽量不使用== 或者!= 来比较,可以使用equal()来实现。

Java中==和equals区别详解

标签:java   比较   

原文地址:http://blog.csdn.net/fuyuwei2015/article/details/45479773

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!