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

 

时间: 2024-10-23 23:51:53

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

java中堆和栈的概念

1.在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 2.堆内存用来存放由new创建的对象和数组. 3.在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量.让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或者对象的引用变量.(引用变量就相当于是为数组或对象起的名字,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象)

java之堆和栈的比较

当我们第一次接触堆和栈时很多人都不不明白java中为什么要设置这两个概念,他们都有什么作用?堆和栈有什么区别,各自都有什么特点?还有Java中存在栈这样一个后进先出(Last In First Out)的顺序的数据结构,这就是java.util.Stack.这种情况下,不免让很多人更加费解前面的问题.事实上,堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存.众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈. 区别

【C++基础 01】堆和栈的概念

好记性不如烂笔头,学习c++的时间也不是很久,趁着这段时间看 <C++ Primer>将学习笔记整理一下,与君共勉. ==================================================================== 首先要区分一下概念: [数据结构的栈和堆] 堆:也叫优先队列,是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等. 栈:具有后进先出性质

Java中堆、栈、方法区的联系

引言:Java中堆.栈.方法区的联系,为了更好的理解三者间的关系,本文用Test类的 声明->调用 来简单的展示这一过程. Test类: 一.编译时 在编译时会将对象Test . 常量和静态方法存入方法区 方法区分为2块: 1.对象区(加载时会将静态成员直接加载进去) 2.常量区 二.实例化时 在对象实例化时,会在堆中为对象分配一块空间. 三.调用对象的方法时 次出有2种情况: 1.静态方法调用 会直接去方法区找到add()方法进栈使用,使用完弹栈. 2.非静态方法调用 原文地址:https:/

java中的堆和栈的概念和区别

在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的.JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方式都不同,所以要单独进行管理. JVM内存的划分有五片: 1.   寄存器: 2.   本地方法区: 3.   方法区: 4.   栈内存: 5.   堆内存. 我们重点来说一下堆和栈: 栈内存:栈内存首先是一片内存区域,

java的堆和栈

Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时 动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配内存,存取速度较慢. 栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享.但缺点是,存在栈中的数据大小

JAVA.C#堆和栈的区别

一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵.3.全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的

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

面试中,有家公司做数据库开发的,对内存要求比较高,考到了这个 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配.你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象. ------最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈(stack).位于通用RAM中,但通过它的“栈指针”可以从处理器哪里获得支持

java中堆和栈的区别

Java的堆是一个运行时数据区,类的(对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等 指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时 动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配内存,存取速度较慢. 栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享.但缺点是,存在栈中的数据大小