当前位置: 首页 > 科技观察

说说javaSE中==和equals的联系和区别

时间:2023-03-18 13:40:51 科技观察

前言==和equals是我们在面试中经常遇到的问题。那么它们之间有什么联系和区别呢?今天就来说说吧!下面是一些典型的笔试题:intx=10;inty=10;Stringstr1=newString("abc");Stringstr2=newString("abc");Stringstr3="abc";Stringstr4="abc";System.out。println(x==y);//输出?System.out.println(str1==str2);//输出?System.out.println(str1.equals(str2));//输出?System.out.println(str3==str4);//输出?System.out.println(str1==str3);//输出?System.out.println(str1.equals(str3));//输出?整数f1=100,f2=100,f3=150,f4=150;System.out.println(f1==f2);//输出?System.out.println(f3==f4);//输出?正文我们通常说“==”是用来判断两个变量之间的值是否相等。变量又分为基本数据类型变量和引用类型。如果是基本数据类型的变量,直接比较值,而引用类型需要比较对应引用内存的首地址。equals方法一般用于比较两个对象看起来是否相同。判断两个对象的某些特征(内容)是否相同。其实就是调用对象的equals方法进行比较。那么我们来看看equals方法吧!equals方法其实是属于Object类的一个方法。因为Object类是所有类的直接或间接父类,也就是说所有类中的equals()方法都是继承自Object类的,通过源码我们发现equals()的底层实现Object类中的方法实际上是"==number.publicbooleanequals(Objectobj){return(this==obj);}那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用“==”符号是一样的,并且也是比较的对象,但是Java提供的大部分类都重写了equals()方法。重写后的equals()方法一般比较两个对象的值,比如String类,Date类,基本数据类型的Wrapper类等。可以看String类的源码:publicbooleanequals(Objectvar1){如果(this==var1){returntrue;}else{if(var1instanceofString){Stringvar2=(String)var1;intvar3=this.value.length;if(var3==var2.value.length){char[]var4=this.value;char[]var5=var2.value;for(intvar6=0;var3--!=0;++var6){if(var4[var6]!=var5[var6]){returnfalse;}}returntrue;}}returnfalse;}}解决方法看完上面的描述,相信你可以答对或回答其中的大部分问题。但需要注意以下两点:Stringstr3="abc";Stringstr4="abc";System.out.println(str3==str4);//输出为true这里为什么为true?按理说str3和str4是两个对象,“==”比较的是地址,应该是false。如果你这么认为,那你就不是很了解String类。String类,我们都知道它是一个不可变的字符序列,存储在常量池中,所以当你声明一个str3="abc"时,它会在常量池中开辟一块内存空间来存储"abc",following再次声明时,会在常量池中查找。如果有,则将当前地址直接赋值给该变量。如果没有,它将被重新创建。所以这里的str3和str4指向同一个内存地址。整数f1=100,f2=100,f3=150,f4=150;System.out.println(f1==f2);//输出trueSystem.out.println(f3==f4);//输出false看上面的答案是不是很意外。其实这里还有一个隐藏的知识点。是包装类的缓存问题。下面简单说明一下:integer和char类型对应的包装类,在自动装箱时会缓存-128到127之间的值。当然,目的是为了提高效率。缓存处理的原则是:如果数据在-128~127范围内,则在类加载时就已经为范围内的每个值创建了对象,并将这256个对象存储在一个名为cache的数组中。每当发生自动装箱过程时(或手动调用valueOf()时),会先判断数据是否在范围内,如果在,则直接获取数组中对应的包装类对象的引用,如果不在在范围内,它会通过new调用包装类的构造函数来创建一个对象。这里我们以Integer类为例,源码参考:低的)];返回新整数(i);//超出范围是新的Integer对象}在这段代码中,我们需要说明以下几个问题:1、IntegerCache类是Integer类的静态内部类,仅供Integer类使用。它的作用是初始化数组缓存,这个过程会在类加载时完成。有兴趣的可以去看哈的源码,这里就不贴了。2、一般情况下IntegerCache.low为-128,IntegerCache.high为127,IntegerCache.cache是??内部类的静态属性。看到这里,相信你已经可以解决上面提出的问题了。答案参考:intx=10;inty=10;Stringstr1=newString("abc");Stringstr2=newString("abc");Stringstr3="abc";Stringstr4="abc";System.out.println(x==y);//输出trueSystem.out.println(str1==str2);//输出falseSystem.out.println(str1.equals(str2));//输出trueSystem.out.println(str3==str4);//输出trueSystem.out.println(str1==str3);//输出falseSystem.out.println(str1.equals(str3));//输出trueIntegerf1=100,f2=100,f3=150,f4=150;System.out.println(f1==f2);//outputtrueSystem.out.println(f3==f4);//outputfalse某500强外企Linux开发工程师徐亮分享很多公众号中的Linux干货,欢迎关注!