Java的equals和==问题
来源:互联网 发布:面试软件开发岗位 编辑:程序博客网 时间:2024/05/16 12:11
Java中equals和==的区别,是十分经典的问题。本人有次面试时,就被问了这个问题。在此深入研究下。
第一原则:
equals和==都是比较变量(varivable)才可以比较。类、方法、接口等非变量是不能比较的。
以下代码,编译器是不能通过的。
eg1:class A{ void fun(){ }}class B{ void fun(){ }}interface C{}interface D{}public class test2 { public static void main(String[] args){ A a = new A(); B b = new B(); System. out.println(A.equals( B)); System. out.println(C.equals( D)); }}
第二原则:
基础数据类型是可以直接用==比较的。
在第一原则的情况下,Java的变量分为基本数据类型和引用型,两者比较是不同的。
首先熟悉下Java的变量存储机制。
1、基本数据类型(包括数值型,字符型和布尔型)在创建时,在栈上给其划分一块内存,将数值直接存储在栈(stack)上。
2、引用数据类型在被创建时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。
在eg1中,A a = new A(),简单的一句话,其实执行了如下的步骤:
step1:在stack区分配了一块区域,存放a;
step2:在heap区新建A的一个对象;
step3:将A对象在堆内存中的地址,赋值给栈中的a,通过句柄a可以找到堆中对象的具体信息。
当我们使用==比较时,比较的是在stack内容中存储的内容,所以基础类型是可以直接用==比较的,那么引用型的呢?
第三原则:
引用型变量的比较,要具体情况具体分析。
结合具体情况是指结合什么东西的具体情况呢,当然是指JDK文档中的不同对象的equals方法了。
情况一:
eg2: class A{ void fun(){ } } public class test2 { public static void main(String[] args){ A a1 = new A(); A a2 = new A(); System. out.println(a1.equals(a2)); } }
打印结果是false,这是怎么回事?当我们新建A对象时,继承的是java.lang.Object,并且没有重写equals方法。而Object类中的equals方法是用来比较“地址”的,所以等于false。
情况二:
eg3: public class test2 { public static void main(String[] args){ String str = new String( "helloworld"); String str2 = new String( "helloworld"); System. out.println(str.equals(str2)); } }
打印结果是true,这是怎么回事?在JDK中String的equals方法已经被重写,比较就是内容,所以等于true。
情况三:
eg4: public class test2 { public static void main(String[] args){ StringBuffer str = new StringBuffer( "helloworld"); StringBuffer str2 = new StringBuffer( "helloworld"); System. out.println(str.equals(str2)); } }
打印结果是false,这是因为StringBuffer并没有重写equals方法,还是比较的地址。
读到这里,大家也许明白了,equals千万不能死记硬背,要根据JDK的文档来查看相应对象的比较方法才行。而我们自己定义的类,如果想用equals的比较的话,就需要重写了。
eg5: class A{ private String age; public String getAge() { return age; } public void setAge(String age) { this. age = age; } public boolean equals(A a) { return this. age.equals(a. age); } } public class test2 { public static void main(String[] args){ A a1 = new A(); a1.setAge( "12"); A a2 = new A(); a2.setAge( "12"); System. out.println(a1.equals(a2)); } }
打印结果是true!
PS:还有一种很特殊的情况,既可以使用equals又可以使用==,这就涉及到Java的装箱拆箱了(详见笔者的另一篇文章:点击打开链接)。
分析:
在C语言中,数组的定义方法有两种:
char a[] = "leirenbaobao"
char *p = "leirenbaobao"
第一种是用数组定义,第二种是用指针指向字符串常量区的一个字符串,而字符串常量区有个特性:当我定义了char *p = "leirenbaobao"时,再定义个char *q = "leirenbaobao",这时候字符常量区不再新建另一个"leirenbaobao",而是将两个指针同时指向一个第一个"leirenbaobao",想必这样也是为了程序执行的效率吧。
而在java中,也是这尿性,java的字符串常量区,有时也被称为字符串常量池。
eg6: public class test2 { public static void main(String[] args){ String str = "leirenbaobao"; String str2 = "leirenbaobao"; System. out.println(str.equals(str2)); System. out.println(str==str2); } }
结果返回两个true。
Ctrl+Z presents!
0 0
- Java的equals和==问题
- 在java中“==”和equals的问题
- java中==和equals问题
- java ==和equals、equals和hashCode的区别
- equals和==引发的问题
- Java的equals和==
- Equals和==的区别,java
- java == 和 equals的区别
- java ==和equals的区别
- java equals和==的详解
- Java "equals"和"=="的区别
- java:equals 和 ==的区别
- Java equals和==的用法
- Java 的==和equals比较
- Java:的“==”和equals方法
- 谈谈java的"=="和equals
- Java "==" 和 .equals()的区别
- java == 和equals的区别
- 天声人語 20141217
- 发送邮件编程原理
- 【Cocos2dx-Lua 脚本开发之二】Lua语言基础
- Java 中的继承
- Android shape的使用实现圆角,虚线,渐变等效果
- Java的equals和==问题
- ArcGIS教程:在ArcGIS下如何合并dem
- oc
- [leetcode]Merge k Sorted Lists
- Eclipse查找替换巧妙技巧用法
- 边记边学PHP-(十三)面向对象编程3
- Windows8下PhoneGap 4 + Android Studio 1.0 + VS2013配置指南
- 学习裸机开发的步骤
- Java泛型(二)泛型的内部原理:类型擦除以及类型擦除所带来的问题