”==“与”equals()”的区别。

一、理解”==“的含义

在java中,主要有两个作用。

1、基础数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。

2、引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。

二、理解equals的含义

源码中说,equals方法是在Object中就有。

从源码中你会发现,比较的是当前对象的引用和obj的引用是否相同,也就是说比较的默认就是地址。还记的在上面我们使用的是User而不是String嘛?在这里==比较的是引用的地址,equals也是比较的是引用的地址,所以他们的效果在这里是一样的。

三、重写equals

1、String中equals方法

看到这个标题相信你已经能找到答案里,Object对象里面的==和equals没有什么区别,这样一看equals方法存在的意义真的不大,不过后来String在Object的基础之上重写了equals,于是功能被大大的改变了。

源码中,我们能够获取到的信息是:String中的equals方法其实比较的是字符串的内容是否一样。也就是说如果像String、Date这些重写equals的类,你可要小心了。使用的时候会和Object的不一样。

2、内存解释

在java中我们一般把对象存放在堆区,把对象的引用放在栈区。因此在上面三个字符串的内存状态应该是下面这样的。

(1)String str1 = "Hello"会在堆区存放一个字符串对象

(2)String str2 = new String("Hello")会在堆区再次存放一个字符串对象

(3)String str3 = str2这时候Str3和Str2是两个不同的引用,但是指向同一个对象。

四、总结

1、基本数据类型作比较只能用“==”,且比较的是值,另外基本数据类型是放在栈中还是放在堆中,这取决于基本类型在何处声明:

 在方法中声明的变量可以是基本类型的变量,也可以是引用类型的变量。

         (1)当声明是基本类型的变量的时,其变量名及值(变量名及值是两个概念)是放在方法栈中

         (2)当声明的是引用变量时,所声明的变量(该变量实际上是在方法中存储的是内存地址值)是放在方法的栈中,该变量所指向的对象是放在堆类存中的。

 在类中声明的变量是成员变量,也叫全局变量,放在堆中的(因为全局变量不会随着某个方法执行结束而销毁)。

 同样在类中声明的变量即可是基本类型的变量 也可是引用类型的变量

       (1)当声明的是基本类型的变量其变量名及其值放在堆内存中的

       (2)引用类型时,其声明的变量仍然会存储一个内存地址值,该内存地址值指向所引用的对象。引用变量名和对应的对象仍然存储在相应的堆中

2、像String、Date这些重写equals的类,都是比较的string对象地址对应的内容,比较的就是值(字符串)

3、引用类型比较 “==” 比较的是内存地址

4、如果是没有重写equel 方法,源码中其实就是比较的内存地址也就是和3一样

5、intern方法,他的意思是检查字符串池里是否存在,如果存在了那就直接返回为true。string a  = ‘AA’   String b=a.代表的是a的地址和b 的地址是同一个,同样内容也是一样的

五、相关知识点

基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上。

引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。

例如,有一个类Person,有属性name,age,带有参的构造方法,

Person p = new Person("zhangsan",20);

在内存中的具体创建过程是:

1.首先在栈内存中位其p分配一块空间;

2.在堆内存中为Person对象分配一块空间,并为其三个属性设初值"",0;

3.根据类Person中对属性的定义,为该对象的两个属性进行赋值操作;

4.调用构造方法,为两个属性赋值为"Tom",20;(注意这个时候p与Person对象之间还没有建立联系);

5.将Person对象在堆内存中的地址,赋值给栈中的p;通过引用(句柄)p可以找到堆中对象的具体信息。

相关知识:

静态区: 保存自动全局变量和 static 变量(包括 static 全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。

堆区:  一般由程序员分配释放,由 malloc 系列函数或 new 操作符分配的内存,其生命周期由 free 或 delete 决定。在没有释放之前一直存在,直到程序结束,由OS释放。其特点是使用灵活,空间比较大,但容易出错

栈区: 由编译器自动分配释放,保存局部变量,栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁,其特点是效率高,但空间大小有限

文字常量区: 常量字符串就是放在这里的。   程序结束后由系统释放。

想要体面生活,又觉得打拼辛苦;想要健康身体,又无法坚持运动。人最失败的,莫过于对自己不负责任,连答应自己的事都办不到,又何必抱怨这个世界都和你作对?人生的道理很简单,你想要什么,就去付出足够的努力。
原文地址:https://www.cnblogs.com/potentPrince/p/12395814.html