转载自:http://www.cnblogs.com/xudong-bupt/p/3960177.html

在Java编程或者面试中经常会遇到 == 、equals()的比较。自己看了看源码,结合实际的编程总结一下。

1. == 

  Java中的==是比较两个对象在JVM中的地址。比较好理解。看下面的代码:

 public class ComAddr{
     public static void main(String[] args) throws Exception {
         String s1 = "nihao";
         String s2 = "nihao";
         String s3 = new String("nihao");
         System.out.println(s1 == s2);    //    true
         System.out.println(s1 == s3);    //    false
     }
 }

  上述代码中:

  (1)s1 == s2为true,是因为s1和s2都是字符串字面值"nihao"的引用,指向同一块地址,所以相等。

  (2)s1 == s3为false,是因为通过new产生的对象在堆中,s3是堆中变量的引用,而是s1是指向字符串字面值"nihao"的引用,地址不同所以不相等。

2.equals()

  equals是根类Obeject中的方法。源代码如下:

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

  可见默认的equals方法,直接调用==,比较对象地址。

  不同的子类,可以重写此方法,进行两个对象的equals的判断。

  String类源码中重写的equals方法如下,

     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;
                 ;
                 ) {
                     if (v1[i] != v2[i])
                             return false;
                     i++;
                 }
                 return true;
             }
         }
         return false;
     }

  从上面的代码中可以看到,

  (1)String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。

  (2)若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。

3.hashcode()

  hashCode是根类Obeject中的方法。

  默认情况下,Object中的hashCode() 返回对象的32位jvm内存地址。也就是说如果对象不重写该方法,则返回相应对象的32为JVM内存地址。

public class Hello {

    public static void main(String args[]) {
        String str = "Hello";
        System.out.println(str.hashCode());
    }
}

执行上面的代码,控制台将打印出:

而String类源码中重写了 hashCode方法,源代码如下:

 public int hashCode() {
     int h = hash;    //Default to 0 ### String类中的私有变量,
     if (h == 0 && value.length > 0) {    //private final char value[]; ### Sting类中保存的字符串内容的的数组
         char val[] = value;

         for (int i = 0; i < value.length; i++) {
             h = 31 * h + val[i];
         }
         hash = h;
     }
     return h;
 }

  String源码中使用private final char value[];保存字符串内容,因此String是不可变的。

  看下面的例子,没有重写hashCode方法的类,直接返回32位对象在JVM中的地址;Long类重写了hashCode方法,返回计算出的hashCode数值:

 public class ComHashcode{
     public static void main(String[] args) throws Exception {
         ComHashcode a = new ComHashcode();
         ComHashcode b = new ComHashcode();
         System.out.println(a.hashCode());
         System.out.println(b.hashCode());    

         Long num1 = new Long(8);
         Long num2 = new Long(8);
         System.out.println(num1.hashCode());
         System.out.println(num2.hashCode());
     }
 }

总的来说:== 比较对象在JVM中的地址。 equals 默认也是比较对象在 JVM 中的地址,但子类可重写该方法实现个性化需求。hashcode 默认返回 对象的 32 位 JVM 内存地址,但子类也可以通过重写该方法实现个性化需求。

除了上面所说的关系之外,equals() 和 hashCode() 还有一些关联特性:

(1)绑定。当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码,即如果两个对象 equals() 相等,那么其调用 hashCode() 的返回值也应该相同。

(2)绑定原因。Hashtable实现一个哈希表,为了成功地在哈希表中存储和检索对象,用作键的对象必须实现 hashCode 方法和 equals 方法。同(1),必须保证equals相等的对象,hashCode 也相等。因为哈希表通过hashCode检索对象。

参考:

http://docs.oracle.com/Javase/7/docs/api/

java中的==、equals()、hashCode()源码分析的更多相关文章

  1. java中的==、equals()、hashCode()源码分析(转载)

    在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...

  2. JAVA设计模式-动态代理(Proxy)源码分析

    在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...

  3. java集合系列之LinkedList源码分析

    java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...

  4. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  5. RocketMQ中Broker的启动源码分析(二)

    接着上一篇博客  [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...

  6. java多线程系列(九)---ArrayBlockingQueue源码分析

    java多线程系列(九)---ArrayBlockingQueue源码分析 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 j ...

  7. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

  8. Java并发系列[2]----AbstractQueuedSynchronizer源码分析之独占模式

    在上一篇<Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析>中我们介绍了AbstractQueuedSynchronizer基本的一些概 ...

  9. Java并发系列[3]----AbstractQueuedSynchronizer源码分析之共享模式

    通过上一篇的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取.在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快 ...

  10. Java并发系列[5]----ReentrantLock源码分析

    在Java5.0之前,协调对共享对象的访问可以使用的机制只有synchronized和volatile.我们知道synchronized关键字实现了内置锁,而volatile关键字保证了多线程的内存可 ...

随机推荐

  1. A manager is becoming more and more popular in China

    A manager is becoming more and more popular in China; many people want to possess a position like th ...

  2. win8下 msvcr100d.dll文件缺失解决方法

    一.如果在运行某软件或编译程序时提示缺少.找不到msvcp100d.dll等类似提示,您可将从载来的msvcp100d.dll拷贝到指定目录即可(一般是system系统目录或放到软件同级目录里面),或 ...

  3. htmlunit 导致高cup占用的坑

    原文:http://blog.csdn.net/qq_28384353/article/details/52974432#reply 将爬虫部署到服务器上运行后,在查看服务器的状态监控时发现,天猫爬虫 ...

  4. TCP/IP协议(零)TCP/IP参考模型

    我们先浏览一下TCP/IP的参考模型,对网络模型有一个大致的了解,后续着重学习OSI参考模型. TCP/IP参考模型是计算机网络的祖父ARPANET和其后继的因特网使用的参考模型. 1.结构 TCP/ ...

  5. Material Design学习-----SnackBar

    SnackBar是一个和Toast类似的空间,用于弹出提示作用,但是相比于Toast而已,SnackBar会有一个不错的动画效果,同时当手指完成屏幕中其他操作的时候,SnackBar会立即消失.同时可 ...

  6. How to build mscorlib.dll with visual studio

    Recently, Microsoft Corportation has released a new look for .NET Reference Source. And you may find ...

  7. 3步轻松搭建Unity3d安卓开发环境

    之前写过一个Untiy3d安卓开发环境的配置教程,那是我第一次学习配置安卓开发环境,互联网上的信息良莠不齐,自己当时也不懂,配置步骤麻烦的一塌糊涂,现在见的多了,也会的多了,配置安卓开发环境变得非常容 ...

  8. Java对象序列化的使用和定制

    序列化的概念及使用场合 序列化就是把对象转化为字节序列并持久化保存,可以保存在内存中.磁盘文件系统,甚至通过网络传递,并能够在以后将这个字节序列完全恢复为原来的对象. 对象序列化的概念引入Java是为 ...

  9. Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 1

    在开发Modbus程序的过程中,也可以发现经常需要使用诸如Modbus Poll和Modbus Slave等辅助调试工具, 用于验证MODBUS通讯消息是否正确.但是,Modbus Poll和Modb ...

  10. html 框架 2017-03-11

    1. 框架frameset   (不在body中编写) Eg: 显示如下框架 第一步: <frameset rows="100,100,*" frmameborder=&qu ...