详解java中equals和== 的区别
2014-03-31 11:52
465 查看
先看一段代码:String test1 = "add";
String test2 = "add";
String test3 = new String("add");
String test4 = new String("add");
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
System.out.println(test3 == test4);
System.out.println(test3.equals(test4));
System.out.println(test1 == test3);
System.out.println(test1.equals(test4));
运行结果:
分析:
结合上面的语句,我简单说一下字符串的赋值过程。当计算机执行Stringtest1 = "add"的时候,它会先检查内存中是否存在存有“add”的地址空间,如果存在,直接将变量test1指向该地址空间。如果不存在,就新建一块地址空间存放“add”,然后将变量test1指向该地址空间。所以,test1和test2实际上指向的是同一地址空间。当计算机执行Stringtest3
= new String("add")时,它会直接在内存中开辟一块地址空间存放“add”,然后将变量test3指向该地址空间。所以最终的内存分布如下图所示:
结论:
从程序的运行结果和上图来看,我们可以得出:“==”比较的是两个变量的存放地址,只要地址不一样,那它们就是不相等。而“equals”要求的条件就没有那么苛刻,只要值相等了,那它就是true。
继续深入:
让我们来看看对象String的equals方法源码:
从源码中我们可以看到,String类重写了Object类的equals方法,它同样使用“==”进行内存地址的比较,但是String类对比较进行了扩展,使之出现与“==”不同的结果。
扩展:
“==”是基类Object的equal实现,不同的类对它进行了不同的重写,进而导致比较的不同。所以,你完全可以新建一个类,然后重写基类的equals方法,让它按照你自己的方式进行比较。当然,重写equals方法的情况较少,可能我们更多用到的是重写toString方法,但是,他们的原理是一样的。
String test2 = "add";
String test3 = new String("add");
String test4 = new String("add");
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
System.out.println(test3 == test4);
System.out.println(test3.equals(test4));
System.out.println(test1 == test3);
System.out.println(test1.equals(test4));
运行结果:
true true false true false true
分析:
结合上面的语句,我简单说一下字符串的赋值过程。当计算机执行Stringtest1 = "add"的时候,它会先检查内存中是否存在存有“add”的地址空间,如果存在,直接将变量test1指向该地址空间。如果不存在,就新建一块地址空间存放“add”,然后将变量test1指向该地址空间。所以,test1和test2实际上指向的是同一地址空间。当计算机执行Stringtest3
= new String("add")时,它会直接在内存中开辟一块地址空间存放“add”,然后将变量test3指向该地址空间。所以最终的内存分布如下图所示:
结论:
从程序的运行结果和上图来看,我们可以得出:“==”比较的是两个变量的存放地址,只要地址不一样,那它们就是不相等。而“equals”要求的条件就没有那么苛刻,只要值相等了,那它就是true。
继续深入:
让我们来看看对象String的equals方法源码:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
从源码中我们可以看到,String类重写了Object类的equals方法,它同样使用“==”进行内存地址的比较,但是String类对比较进行了扩展,使之出现与“==”不同的结果。
扩展:
“==”是基类Object的equal实现,不同的类对它进行了不同的重写,进而导致比较的不同。所以,你完全可以新建一个类,然后重写基类的equals方法,让它按照你自己的方式进行比较。当然,重写equals方法的情况较少,可能我们更多用到的是重写toString方法,但是,他们的原理是一样的。
相关文章推荐
- Java中==和equals区别详解
- java equals和==的区别详解
- Java中==运算符与equals方法的区别及intern方法详解
- (详解)Java equals方法与==的区别和联系
- Java中equals和==的区别 (详解)
- java 中==和equals区别详解
- 详解 Java 中 equals 和 == 的区别
- 详解Java中“==”与equals()的区别
- java中==和equals的区别详解
- java字符串的替换replace、replaceAll、replaceFirst的区别详解
- java基础——“==”与equals方法的区别
- java之yield(),sleep(),wait()区别详解-备忘笔记
- java中==与equals的区别
- java中equals和==的区别
- 详解java重载与覆写的区别
- Java修饰符 abstract,static,final 的区别详解
- java中的equals()方法和hashCode()方法详解
- JAVA中null,"",equals,==相互之间使用详解
- Java面试——从JVM角度比较equals和==的区别
- JAVA中字符串比较equals()和equalsIgnoreCase()的区别