Java中equals与==异同

Java中equals与==异同Posted on

为了更好的理解,先来看看java的数据类型java的数据类型分为两大类:基本数据类型与引用数据类型。

基本数据类型有8种:数值型:byte int short long字符型:char布尔型:bool

引用数据类型有3种:类:Class接口:Interface数组:Array

再有,基本数据类型也有与自己相对应的封装类,即引用类型:数值 :Byte、Short、Integer、Long、Float、Double字符:Character布尔:Boolean

在java中基本数据类型都被统一放在一块区域(内存的栈中),其中有一部分区域称之为“常量池”。在常量池中,基本数据类型可以被共享,也就是说我们定义一个int a = 5;然后又定义了一个int b = 5;这时a与b在内存中指向的是同一个5。而对于引用数据类型来说,一个引用数据类型的变量保存的就是这个引用数据类型的引用,即地址。如:String s = “abc” s保存的就是一个地址。

好了 现在进入正题: equals与==的区别简单来说:equals比较的是值,==比较的是地址。带着这样的前提会帮你理解下面的废话…

看下面一段代码:

1 String s1 = new String(“abc”);2 String s2 = “abc”;3 if(s1 == s2){4   System.out.println(“s1 == s2”);5 }6 if(s1.equals(s2)){7   System.out.println(“s1 equals s2”);8 }

输出结果是:“s1 equals s2”。这是为什么?,s1与s2明明都是”abc”呀,难道“s1 != s2”吗。

事情是这个样子的:虽然两个语句都是返回一个String对象的引用,但是jvm对两者的处理方式是不一样的。对于第一种,jvm会马上在heap中创建一个String对象,然后将该对象的引用返回给用户。对于第二种,jvm首先会在内部维护的strings pool(可以称之为字符串池)中通过String的 equels 方法查找是strings pool中是否存放有该String对象,服务器空间,如果有,则返回已有的String对象给用户,而不会在heap中重新创建一个新的String对象;如果strings pool中没有该String对象,jvm则在heap中创建新的String对象,将其引用返回给用户,同时将该引用添加至strings pool中。注意:使用第一种方法创建对象时,网站空间,jvm是不会主动把该对象放到strings pool里面的,除非程序调用String的intern方法:str.intern();

intern是这样工作的:首先查看strings pool中有无“abc”对象的引用,有则返回那个”abc”的引用。没有,则在堆中新建一个对象,然后将新对象的引用加入到strings pool中。

是不是很眼熟,没错,这不就是刚刚第一个代码例子中 String s2 = “abc”;的时候jvm所做的事情么。所以说,用String来声明字符串,结果都会至少有一个String对象存在的。与之对应的基本数据类型的封装类中有一些也具有常量池技术:这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。并且Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127时才可使用对象池,也即对象不负责创建和管理大于127的这些类的对象。

明白原理之后回头再看看:来看看==:通常可以这样定义一个变量:int a = 1; int b = 1;a与b都是基本数据类型,会被放在常量池中,而且此时因为java的常量池共享,香港虚拟主机,此时常量区中只有一个1,所以if(a == b)返回位true。因为a和b的无论是值还是地址都是相等的。(这里不能用equals比较,因为equals是Object类的方法。)

现在看看equals:上面说了,equals是继承自Object类的一个方法,所以所有引用类型都可以使用equals方法。然后记住:声明一个类的实例,要用new关键字 ,所以String str1 = “hello world”;String str2 = “hello world”; 这两个肯定是相等的,因为没有用到new 所以java虚拟机会与处理基本类型一样,去常量池查看是否已存在一个”hello world”,如果有则不再新增,str1,str2都指向这个”hello world”。我们可以用new关键字这样实例化一个String对象:String s1 = new String(“abc”) ; String s2 = new String(“abc”)。s1 与 s2 是引用数据类型 所以if(s1.equals(s2))返回的是true,而if(s1 == s2)则返回false。这是因为s1与s2都是有用new关键字声明出的新对象,各自有各自的地盘,互不相干。虽然值是一样的,但是存储的位置却不一样,就好像一个楼里有两个同名的人,但是两人住不是一个房间,你对其一操作,不会影响另一个。所以==所比较出的是地址是否相同。当然是false了。这也证实了开始说的:equals比较的是值,==比较的是地址。

另外:Object类中的equals方法,其代码就是==操作。在没有复写Object的equals方法时调用的话,其实就是使用==。固有的引用数据类型已经复写了equals方法,如String类。

Object类中的equals方法:

equals(Object obj) {2return (this == obj);3 }

爱情要完结的时候自会完结,到时候,你不想画上句号也不行。

Java中equals与==异同

相关文章:

你感兴趣的文章:

标签云: