在学习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. 关于新版ADT创建项目时出现appcompat_v7的问题

    做Android开发的朋友最近会发现,更新ADT至22.6.0版本之后,创建新的安装项目,会出现appcompat_v7的内容.并且是创建一个新的内容就会出现.这到底是怎么回事呢?原来appcompa ...

  2. 探索模拟angular的双向绑定

    前言 本次探索的demo是基于jquery写的,毕竟jquery提供了强大的选择器,用惯了就离不开它了!angular的双向绑定实在是有点精深,本次探索只实现了文本的双向绑定. View-Model ...

  3. 正则表达式/g与/i及/gi的意义

    g: 全局匹配 i: 忽略大小写 gi: 全局匹配 + 忽略大小写

  4. GPS部标平台的架构设计(四)-百度地图设计

    部标GPS软件平台之百度地图设计 地图是客户端中不可缺少的一个模块,很多人在设计和画图时候,喜欢加上地图引擎这样高大上的字眼,显得自己的平台有内涵,说白了就是用第三方的SDK来开发,早期的GPS监 控 ...

  5. Spark on Yarn:java.sql.SQLException: No suitable driver found for jdbc:microsoft:sqlserver://localhost\\db_instance_name:1433;databaseName=db_name

    本文只是针对当前特定环境下,出现的问题找不到sqljdbc驱动的案例.具体出现原因,可能是spark版本问题,也可能是集群配置问题. yarn-client方式下: 通过--jars参数指定驱动文件位 ...

  6. DataAnnotations里DisplayAttribute和 ValidationAttribute 如何从资源文件读取信息,显示多语言

    这个是我们常见的AccountModel代码 public class ChangePasswordModel { [Required] [DataType(DataType.Password)] [ ...

  7. memcache的最佳实践方案

    1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 1 ...

  8. nodejs cookie管理

    Cookie 管理 我们可以使用中间件向 Node.js 服务器发送 cookie 信息,以下代码输出了客户端发送的 cookie 信息: // express_cookie.js 文件 var ex ...

  9. 理解timestamp

    大多数资料都说timestamp表示自从1970-1-1 00:00:00开始到现在的秒数,一般称为epoch time,却忽略了时区的概念.其实,不同时区记录timesamp的基准时间是不一样的,比 ...

  10. mysql 增删改查最基本用法小结

    目录: 1.新建数据库 2.新建数据表 3.查看表结构 4.增删改查 建立一个数据库students 建立一块数据表class1 内容包括: id 主键 自动编号 无符号位 SMALLINT类型 na ...