关于深入分析“==” 和 equals()。
总的来说:
一、对于==,比较数值是否相等
当比较对象为基本数据类型时,那么将比较其数值是否相等。
当比较对象为引用数据类型时,那么比较的是引用所指向的对象的地址值。
二、对于equals(),需要注意的是,equals方法并不能用于对基本数据类型的比较,其继承于object类,比较的是是否为同一个对象。
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址。
如果对equals方法进行重写,将比较对象的内容,例如String类,Data类实现了对equals方法的重写。
所以当equals方法不重写时,关于对引用数据类型的判断是看似没有区别的
下面分析一下“equals”
下面我们看一下object类中的equals方法
1 | public boolean equals(Object anObject) { |
我们不难发现,在object类中直接用==判断两个引用的地址是否相同,不会判断引动所指对象的内容跟
而在String类中,重写了equals方法 ,可以对字符串的内容进行判断
1 | public boolean equals(Object anObject) { |
下面分析一下“==”
首先我们要牢记一点不要用==来判断字符串,但当出现一些面试题目时,我们也应该有所了解,下面将举出几个例子来区分,常量池与堆空间对字符串的储存
1 | String s1 = "abc"; |
下面我们出个分析,首先我们要知道通过字面量定义的字符串将声明在常量池中,通过new方法+构造器的方式创建的字符串声明在堆空间中。
① s1与s2在常量池中,此时两个指向相同的地址
② s3声明在堆空间中,显然两者不只想相同的地址
③⑦
1 | graph LR |
s8和s3的地址是相同的,直接引用传递,而s3和s4是不同的,s4新建了堆空间
④显然s3和s4的内容是相同的
⑤只要有变量参与,那么s6将声明在堆空间中,所以s5和s6地址是不同的
⑥s5现在常量池中声明了abcde,s7没有变量参与,所以将和s5的地址相同
总结
1.首先切记基础数据类型不要用equals,比较字符串不要用==;
2.若想比较对象内容,重写equals方法
3.一个小问题:当调用intern()方法后,返回值将在常量池中,此时再根据情况判断地址值是否相同