一、(==)与equals的区别
1、双等号(==)的用法
对基本数据类型(byte,short,char,int,float,double,long,boolean)而言,(==)比较的是它们的值的大小;
对引用类型而言,(==)比较的是它们在内存中的地址,所以除非是同一个new出来的对象,它们的(==)比较结果为true,其余均为false。
2、equals的用法
equals是Object类的方法,该方法初始行为是比较对象在内存中的地址,但对于重写了该方法的类而言则另当别论,如String中的equals
方法是在两个String内容完全相同时返回true,并不在乎是否是同一对象。
二、概念清晰化
1、String使用private final char value[]来实现字符串的存储,也就是说String对象在创建之后,就不能再修改此对象中存储的字符串内容。
正因如此,我们说String是不可变的。
2、String有一个特殊的构建方法,就是使用""来直接进行创建,也就是采用直接量的形式,如:String s = "abc"。这样我们就创建了一个字
符串对象,该对象在创建时,会现在字符串常量池中进行查找,如果存在"abc"的话,则不创建新的对象,直接将引用指向原有的"abc"对象即
可;如果没有的话,会在字符串常量池中创建"abc"对象。
3、String还有一个创建方法,即通过new来创建。比如:String s = new String("abc"); 面试时通常会问该语句创建了几个对象,下面我们
来详细分析一下。(1)该语句首先会在堆中创建一个"abc"对象,然后将引用指向该对象;(2)去字符串常量池中查看,是否存在该对象;(3)若存在,
则将堆中new出来的对象与字符串常量池中内容相同的对象关联起来;(4)若不存在,则在字符串常量池中再创建一个与该对象内容相同的字符串
对象,并将字符串常量池中刚创建的对象与堆中对象关联起来。回到这个问题,如果字符串常量池中不存在"abc"的话,该语句创建了两个对象。
三、实例为证
import java.lang.Class; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class Offer { public static void main(String[] args) { String s1 = "abc888"; String s2 = "abc888"; String s3 = new String("abc888"); String s4 = new String("abc888"); String s5 = s3.intern(); String s6 = "abc" + "888";//在编译期就可确定,与"abc888"等效 String s7 = new String("888"); String s8 = "abc" + s7;//由于s7是变量,在编译器不能确定它的值,所以会在执行的时候在堆中创建一个新的对象 System.out.println("s1 == s2 结果为:" + (s1 == s2));//s1、s2指向了常量池中同一个"abc" System.out.println("s3 == s1 结果为:" + (s3 == s1));//s1与s3指向了不同对象 System.out.println("s3.equals(s1) 结果为:" + s3.equals(s1));//String中equals比较的是二者的内容 System.out.println("s3 == s4结果为:" + (s3 == s4));//new在堆中创建了两个不同的对象 System.out.println("s5 == s1 结果为:" + (s5 == s1));//s3.intern()获取的是s3在常量池中对应对象。 System.out.println("s5.equals(s1) 结果为:" + s5.equals(s1));// System.out.println("s6 == s1结果为:" + (s6 == s1)); System.out.println("s1 == s8结果为:" + (s1 == s8)); System.out.println("s1.equals(s8.intern())结果为:" + s1.equals(s8.intern())); } }
运行结果:s1 == s2 结果为:true s3 == s1 结果为:false s3.equals(s1) 结果为:true s3 == s4结果为:false s5 == s1 结果为:true s5.equals(s1) 结果为:true s6 == s1结果为:true s1 == s8结果为:false s1.equals(s8.intern())结果为:true