在学习java基本数据类型和复杂数据类型的时候,特别是equals()"=="和hashcode()部分时,不是很懂,也停留了很长时间,最后终于有点眉目了。

要理解equals()"=="和hashcode(),最好先了解Java内存中堆和栈的知识:

下面一段是参考自http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

大家也可点进去查看更详细的解释。

Java 中的堆和栈 

  Java把内存划分成两种:一种是栈内存,一种是堆内存。

  1、在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。例如:

int a =10;
String str;

这些都是在栈中分配内存。  

  2、定义数组和类时都在函数的堆内存中分配。例如:

String str =new String();
int []num=int [2]{2,3};

  这些都是在堆中分配内存。堆内存用来存放由new创建的对象和数组。

Java中栈内存和堆内存的优缺点:

Java的栈是一个静态数据区,在程序编译时边分配空间。

Java的堆是一个运行时数据区,类的对象以及数组从中分配空间。这些对象通过new指令建立,它们不需要程序代码来显式的释放。JVM虚拟机中存在垃圾回收机制,堆就是由垃圾回收机制来负责的。

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

栈有一个很重要的性质,就是存在栈中的数据可以共享。例如:

int a =5;
int b =5;

a和b都是在栈中分配内存的

程序先给a分配内存,并存入5

程序给b分配内存时,先检查内存中是否存在5,

发现存在5,直接把b指向内存中存储5所在的地址。

即实现了数据的共享性,不可重复性。

如果后面再加一句:

int a =5;
int b =5;
b = 4;

前两句执行情况和前面相同,

第三句时,由于该函数的栈内存中没有存入4,

故会重新为b分配内存,并存入4

用堆和栈的概念来理解equals() "=="和hashcode()

1、对于(int, short, long, byte, float, double, boolean, char)基本数据类型,比较其是否指向同一个对象时用"=="

double a = 2.5;
double b = 2.5;
System.out.println(a==b);

结果是: true

原因:对于double基本数据类型,其内存是在栈中分配的,由于栈内存的可共享性,故a,b指向同一个内存空间,及同一个对象。

    而"=="的作用是比较两个变量是否指向同一个对象,故此处为true

2、对于类,数组等复杂数据类型时,比较其内容是否相等时用equals()和hashcode()

        String string = new String("hello");
String string2 = new String("hello");
System.out.println(string.hashCode());
System.out.println(string2.hashCode());
System.out.println(string.equals(string2));
System.out.println(string == string2);

结果是:

99162322
99162322
true
false

原因:

对于String,Integer等用类封装的数据类型,其有hashcode()方法。

hashcode()其实就是对其内容进行某种算法,最后得出一个数值(可能不是这样)。

所以说,内容一样,hash值一样。

对于String,Integer等用类封装的数据类型,同样有equals()方法,其作用于”==“相同,用于判断引用类型是否指向同一个对象。

但是

当用equals()方法进行比较时,对类File、String、Date及封装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个对象;

原因:在这些类中覆盖了equals()方法,用于比较内容是否相同。

所以此处虽然不是同一个对象,但是equals()方法仍然返回true

此处因为string和string2都属于复杂数据类型,所以其内存都是在堆中分配的,

而堆中所存储的数据可以重复,故string和string2所指向的不是同一个对象,

所以 string == string2的结果是false

 

JAVA中用堆和栈的概念来理解equals() "=="和hashcode()的更多相关文章

  1. java之堆和栈的比较

    当我们第一次接触堆和栈时很多人都不不明白java中为什么要设置这两个概念,他们都有什么作用?堆和栈有什么区别,各自都有什么特点?还有Java中存在栈这样一个后进先出(Last In First Out ...

  2. Java中堆和栈的区别(转)

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

  3. Java中堆与栈

    简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...

  4. java的堆,栈,静态代码区 详解

    面试中,有家公司做数据库开发的,对内存要求比较高,考到了这个 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方— ...

  5. 通俗的理解java的堆和栈

    堆 可以把堆理解为一家餐厅,里面有200张桌子,也就是最多能同时容纳200桌客人就餐,来一批客人就为他们安排一些桌子,如果某天来的客人特别多,超过200桌了,那就不能再接待超出的客人了.当然,进来吃饭 ...

  6. 让你彻底明白JAVA中堆与栈的区别

    原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...

  7. Java虚拟机堆和栈详细解析,以后面试再也不怕问jvm了!

    堆 Java堆是和Java应用程序关系最密切的内存空间,几乎所有的对象都放在其中,并且Java堆完全是自动化管理,通过垃圾收集机制,垃圾对象会自动清理,不需自己去释放. 根据垃圾回收机制的不同,Jav ...

  8. java中堆与栈的区别

    堆与栈都是java中常用的存储结构,是内存中存放数据的地方. 堆:主要存放运行时创建(new)的对象.主要用于储存对象,存取速度慢,可以运行时动态分配内存,生命周期不需要提前确定. 栈:主要存放基础类 ...

  9. 【转】Java中堆和栈的区别

    Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收 ...

随机推荐

  1. JavaScript第一天 改变DIV的样式

    onmouseover 当鼠标移到这个对象之上时响应 onmouseout 当鼠标移出这个对象之上时响应 document.getElementById('id')   获取id的元素并可以做一些操作 ...

  2. android studio 2.0 GPU Debugger使用说明

    GPU Debugger GPU Debugging Tools The GPU debugging tools are an experimental feature intended to hel ...

  3. Mac上安装django

    参考:https://docs.djangoproject.com/en/1.9/topics/install/#installing-official-release 升级pip sudo pip ...

  4. Runtime实战之定制TabBarItem大小

    方案一:UIEdgeInsets 适用场景: 适合APP的TabBarItemImage的图片资源放在本地 图片超出tabbar的高度,需移动其位置,来进行适应 弊端: 若在本地配置好后,tabbar ...

  5. 微信支付开发(7) H5支付

    关键字:微信支付 微信支付v3 H5支付 wap支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3_h5.html 本文 ...

  6. C#写入日志信息到文件中

    为了在服务器上运行程序及时的跟踪出错的地方,可以在必要的地方加入写日志的程序. string folder = string.Format(@"D:\\{0}\\{1}", Dat ...

  7. docker 服务升级

    使用docker大家一般都是微服务部署了.个人的经验是乖乖的用docker自己的注册发现机制. 创建一个overlay类型的network.把所有的微服务加入进去.就可以把service name当作 ...

  8. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版新增消息管理

    在V3.0版本的Web(Mvc.WebForm)与WinForm中我们新增了“消息管理”模块.“消息管理”模块是对框架的所有消息进行管理.通过左侧的消息分类可以查看所选分类的所有消息列表.在主界面上我 ...

  9. 3.Java Script 类型

     true: null==undefinedfalse: null===undefined   

  10. C# 连接Oracle ,免安装客户端

    在.NET平台下开发Oracle应用的小伙伴们肯定都知道一方面做Oracle开发和实施相比SqlServer要安装Oracle客户端(XCopy.自己提取相关文件也有一定复杂性),另一方面相比JAVA ...