在学习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. C++ Windows 下 根据进程名获取进程ID 以及该进程下所有窗口的句柄

    #include <windows.h> #include <stdint.h> #include <tlhelp32.h> #include <stdio. ...

  2. javascript类型与类型检测

    1.javascript类型: 注:包装对象:如"hello".length实际为js为我们隐式创建了一个String临时对象,去调用该对象的length属性,调用过后再将该临时对 ...

  3. ssh无密码通信设置

    ■单向登陆配置:1.在本地机器中的~/.ssh/目录下执行下命令#ssh-keygen -t dsa然后全部回车,采用默认值.生成了一对密钥,id_dsa和id_dsa.pub,存放在用户目录的~/. ...

  4. shell十三问

    1) 为何叫做 shell ?在介绍 shell 是甚幺东西之前,不妨让我们重新检视使用者与计算机系统的关系:图(FIXME)我们知道计算机的运作不能离开硬件,但使用者却无法直接对硬件作驱动,硬件的驱 ...

  5. JQuery插件开发简单实例

    经常使用Jquery的各种插件,却对如何开发插件一无所知,以为是一件很麻烦的事儿?其实不然,下面通过一个简单的实例,来看一下Jquery Plugin的开发. 先看DEMO:动画菜单 不用插件如何实现 ...

  6. AppSettings和connectionStrings的却别(转)

    AppSettings是ASP.NET1.1时期用的,在.NET Framework 2.0中,新增了ConnectionStrings. 1.<connectionStrings> &l ...

  7. struts-OGNL

    特点 常用来访问值栈里对象属性的一种语言 通常由struts标签来解析执行 <%@ taglib prefix="s" uri="/struts-tags" ...

  8. jdbc 数据的增删改查的Statement Resultset PreparedStatement

    完成数据库的连接,就马上要对数据库进行增删改查操作了:先来了解一下Statement 通过JDBC插入数据 (这里提供一个查找和插入方法) Statement:用于执行sql语句的对象: *1.通过C ...

  9. HDU 5053 the Sum of Cube(简单数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5053 题目大意: 求出A^3+(A+1)^3+(A+2)^3+...+B^3和是多少 解题思路: 设f(n)=1 ...

  10. Android 蓝牙API详解

    随着近两年可穿戴式产品逐渐进入人们的生活,蓝牙开发也成为了Android开发的一个重要模块,下面我们就来说一说蓝牙的这些API. 1.蓝牙开发有两个主要的API: BuletoothAdapter:本 ...