Java中==和equals区别详解

首先来说下两种比较符的使用场景:

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()来实现。

时间: 2024-11-10 12:59:13

Java中==和equals区别详解的相关文章

Java中的main()方法详解

在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等. 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这个例子说明Java类中main()方法的奥秘,程序的代码如下: 1 /** 2 * Java中的main()方法

java中的io系统详解

java中的io系统详解 分类: JAVA开发应用 笔记(读书.心得)2009-03-04 11:26 46118人阅读 评论(37) 收藏 举报 javaiostreamconstructorstringbyte 相关读书笔记.心得文章列表 Java 流在处理上分为字符流和字节流.字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符.字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组. Java 内用 Unicode 编码存储字符,字符流处理类负责将外部的其他

javascript中=、==、===区别详解

javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题,却有着大影响,所以决定深入分析下.1.= 赋值运算符 //例: var n=1; console.log(n);//1 n=n+1; console.log(n);//2 2.== 值比较运算符 值比较运算符在表达式两边的数据类型不一致时,会隐式转换为相同数据类型,然后对值进行比较. //例: var a=

java中System.getProperty()方法详解

java中System.getProperty()方法详解,如下: System.out.println("java版本号:" + System.getProperty("java.version")); // java版本号 System.out.println("Java提供商名称:" + System.getProperty("java.vendor")); // Java提供商名称 System.out.println

Java I/O : Java中的进制详解

作者:李强强 上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算.这一讲,泥瓦匠带你走进Java中的进制详解. 一.引子 在Java世界里,99%的工作都是处理这高层.那么二进制,字节码这些会在哪里用到呢? 自问自答:在跨平台的时候,就凸显神功了.比如说文件读写,数据通信,还有Java编译后的字节码文件.下面会有个数据通信的例子哦. Java对对象实现Serializablle接口,就可以将其转化为一系列字节,而在通信中,不必要关系数据如何在不同机器表示和字节的顺

Java:集合类的区别详解

Java中集合类的区别 Array是数组,不在集合框架范畴之内,一旦选定了,它的容量大小就不能改变了,所以通常在编程中不选用数组来存放. 集合 : 集合对象:用于管理其他若干对象的对象 数组:长度不可变 List: 有顺序的,元素可以重复 遍历:for .迭代 排序:Comparable Comparator Collections.sort() ArrayList:底层用数组实现的List 特点:查询效率高,增删效率低 轻量级 线程不安全 LinkedList:底层用双向循环链表 实现的Lis

Java中&amp;、|、&amp;&amp;、||详解

1.Java中&叫做按位与,&&叫做短路与,它们的区别是: & 既是位运算符又是逻辑运算符,&的两侧可以是int,也可以是boolean表达式,当&两侧是int时,要先把运算符两侧的数转化为二进制数再进行运算,而短路与(&&)的两侧要求必须是布尔表达式.举例如下: 12&5 的值是多少?答:12转成二进制数是1100(前四位省略了),5转成二进制数是0101,则运算后的结果为0100即4 这是两侧为数值时: 若 int i = 2,j

HTTP协议报文、工作原理及Java中的HTTP通信技术详解

一.web及网络基础       1.HTTP的历史            1.1.HTTP的概念:                 HTTP(Hyper Text Transfer Protocol,超文本传输协议)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器.                 它是一个应用层协议,承载于TCP之上.由请求和响应构成,是一个标准的客户端服务器模型            1.2.HTTP的发展历史:          

java中过滤器和监听器详解

先说一下java中过滤器的作用: 过滤器是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url.主要为了减轻服务器负载.减少压力 拦截器的作用: 拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法.比如可以用拦截器做一些权限管理 或者log之类的事情. 过滤器和拦截器他们的作用是不同的.   Java中过