JAVA中用堆和栈的概念来理解equals() "=="和hashcode()
在学习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()的更多相关文章
- java之堆和栈的比较
当我们第一次接触堆和栈时很多人都不不明白java中为什么要设置这两个概念,他们都有什么作用?堆和栈有什么区别,各自都有什么特点?还有Java中存在栈这样一个后进先出(Last In First Out ...
- Java中堆和栈的区别(转)
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...
- Java中堆与栈
简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...
- java的堆,栈,静态代码区 详解
面试中,有家公司做数据库开发的,对内存要求比较高,考到了这个 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方— ...
- 通俗的理解java的堆和栈
堆 可以把堆理解为一家餐厅,里面有200张桌子,也就是最多能同时容纳200桌客人就餐,来一批客人就为他们安排一些桌子,如果某天来的客人特别多,超过200桌了,那就不能再接待超出的客人了.当然,进来吃饭 ...
- 让你彻底明白JAVA中堆与栈的区别
原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- Java虚拟机堆和栈详细解析,以后面试再也不怕问jvm了!
堆 Java堆是和Java应用程序关系最密切的内存空间,几乎所有的对象都放在其中,并且Java堆完全是自动化管理,通过垃圾收集机制,垃圾对象会自动清理,不需自己去释放. 根据垃圾回收机制的不同,Jav ...
- java中堆与栈的区别
堆与栈都是java中常用的存储结构,是内存中存放数据的地方. 堆:主要存放运行时创建(new)的对象.主要用于储存对象,存取速度慢,可以运行时动态分配内存,生命周期不需要提前确定. 栈:主要存放基础类 ...
- 【转】Java中堆和栈的区别
Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收 ...
随机推荐
- notepad++快捷键大全
Ctrl+C 复制 Ctrl+X 剪切 Ctrl+V 粘贴 Ctrl+Z 撤消 Ctrl+Y 恢复 Ctrl+A 全选 Ctrl+F 键查找对话框启动 Ctrl+H 查找/替换对话框 Ctrl+D 复 ...
- MS SQL数据类型比较
字符串数据类型 char此数据类型可存储1~8000个定长字符串,字符串长度在创建时指定:如未指定,默认为char(1).每个字符占用1byte存储空间.nchar此数据类型可存储1~4000个定长U ...
- 使用RestTemplate发送post请求
最近使用RestTemplate发送post请求,遇到了很多问题,如转换httpMessage失败,中文乱码等,调了好久才找到下面较为简便的方法: RestTemplate restTemplate ...
- C#类继承和接口继承时一些模棱两可的问题[转]
原文地址:http://www.cnblogs.com/harleyhu/archive/2012/11/29/2794809.html 1.在father定义的方法若含有virtual关键字,chi ...
- ssh无密码通信设置
■单向登陆配置:1.在本地机器中的~/.ssh/目录下执行下命令#ssh-keygen -t dsa然后全部回车,采用默认值.生成了一对密钥,id_dsa和id_dsa.pub,存放在用户目录的~/. ...
- C学习笔记 知识集锦(二)
1. 数组和指针 2. 字符串赋值 3. memset&memcpy 4. 机器数和真值,原码,反码和补码 5. 文件指针和文件描述符 6. 内存泄露和内存损坏 7. 什么是不可移植的程序 ...
- windows下mysqlbinlog二进制恢复
Mysql数据恢复主要针对Windows游戏引擎服务器意外宕机,以及游戏出现重大BUG,导致需要回档. 注意:请在恢复数据库之前,备份目标数据库,切记! 一.Windows服务器意外DOWN机,数据库 ...
- 可爱的Python_课后习题_CDay−5 Python 初体验和原始需求
计算今年是否是闰年.判断闰年条件,满足年份模400 为0,或者模4 为0 但模100不为0. def is_learp_year(year): """判断年份是否为润年& ...
- https 与http 的坑
网页报这种错误: (blocked:mixed-content) 使用了https就不能夹生http jquery.min.js:4Mixed Content: The page at ' ...
- ios - 谓词的使用
谓词在搜索的时候非常管用.简单示例代码如下: 分类Person.h文件 #import <Foundation/Foundation.h> @interface Person : NSOb ...