前段时间写网站, 在 servlet 中要对用户输入的密码做判断, 就出现一个很奇怪的现象: if 条件句中如果用 "==" 作判断条件, 就没法通过验证, 而一换成 equlas()函数, 就完美解决了, 于是就准备找个时间好好查查原因, 并记录下来, 以备记录.
看了网上许多大佬们的解释, 用一句话来说就是:"==" 是一个参考比较, 即两个对象指向相同的内存位置, 而 equals()函数则是评估对象中值的比较, 相当于查看该地址中存储的内容是否相同.
-------------------------- 分割线 ----------------------------------------
下面是我看的一篇很不错的博文(博文地址:)
要想充分了解 == 和 equals 的区别需要对 java 的内存有所了解:
Java 内存模型中存在这两种内存区域: 一种是栈内存, 一种是堆内存. (注: 程序计数器, 运行时数据区, 永久代, 直接内存这里不讨论, 因为 java 对象保存在栈内存 (基本数据类型) 和堆内存 (引用数据类型和包装类) 中)
在函数中定义的一些基本类型的变量和对象的引用变量 (变量名) 都在函数的栈内存中分配.
当在一段代码块定义一个变量时, Java 就在栈中为这个变量分配内存空间, 当超过变量的作用域后, Java 会自动释放掉为该变量所分配的内存空间, 该内存空间可以立即被另作他用.
堆内存用来存放由 new 创建的对象 (包括由基本类型包装起来的类: Integer,String,Double, 实际上每个基本类型都有他的包装类) 和数组.
一), 基本数据类型:
== 比较值是否相等, 因为基本类型不是对象, 所以没有 equals 方法.
二), 对象
Object 类中的 equals 方法:
- Object.class:
- publicboolean equals(Object anObject) {
- if (this == anObject) {
- returntrue;
- }
- }
可以看出最初的 equals 方法与 == 作用相同, 都是判断内存地址是否相同,
然而 String 类是一个特例,
观察下面例子:
- Stringa="aaa";
- Stringb="aaa";
System.out.println(a==b); 返回 true
System.out.println(a.equals(b)); 返回 true
== 依然比较的是对象的内存地址, 因为 a 和 b 同时指向存放在常量池里的 "aaa" 这个内存地址.
String 类中的 equals 方法:
- Stringstr=new String("aaa");
- Stringstr1=new String("aaa");
- System.out.println(str==str1);
- System.out.println(str.equals(str1));
上面代码返回的是 false true,
False 很容易理解:== 比较的是两个对象的内存地址, 故不相等, 输出 false.
equals 方法用的是 String 类重写 object 类的 equals 方法(其他类里也有 equals 方法).
- String.class:
- publicboolean equals(Object anObject) {
- if (this == anObject) {
- returntrue;
- }
- if (anObjectinstanceof String) {
- String anotherString = (String)anObject;
- intn = value.length;
- if (n == anotherString.value.length) {
- charv1[] = value;
- charv2[] = anotherString.value;
- inti = 0;
- while (n-- != 0) {
- if (v1[i] != v2[i])
- returnfalse;
- i++;
- }
- returntrue;
- }
- }
- returnfalse;
- }
从上面可以看出, 用 == 判断对象的地址是否相等, 相等则返回 true.
如果前面的判断不成立, 接着判断括号内的对象上是否是 String 类型, 接着判断两个字符串对象的的长度是否相等, 最后判断内容是否相等, 如果相等则返回 true.
- int i1 = 1;
- int i2 =1;
- System.out.println(i1 == i2);// 返回 true; 基本变量因为不是对象, 所以没有 equals 方法;
- String a = new String("aaa");
- String b = "aaa";
- System.out.println(a == b);// 返回 false;new 出来的对象重新分配内存地址
- System.out.println(a.equals(b)); // 返回 true;String 类重写了 equals 方法
- StringBuffer sb1 = new StringBuffer("aaa");
- StringBuffer sb2 = new StringBuffer("aaa");
- System.out.println(sb1 == sb2);// 返回 false;new 出来的对象都重新分配内存地址
- System.out.println(sb1.equals(sb2));// 返回 false;StringBuffer 类继承 Object 类的 equals 方法, 实际比较的是内存地址
- String str1 = new String("111");
- String str2 = new String("111");
- System.out.println(str1 == str2);// 返回 false;new 出来的对象都重新分配内存地址
- System.out.println(str1.equals(str2));// 返回 true;String 类重写了 equals 方法
- Integer in1 = new Integer(1);
- Integer in2 = new Integer(1);
- System.out.println(in1 == in2);// 返回 false;new 出来的对象都重新分配内存地址
- System.out.println(in1.equals(in2));// 返回 true; 除了 String 类重写了 equals 方法, 其他都与 Object 类的 equals 方法一致;
总结:
(1) == 比较的是 (基本变量 / 引用变量) 所指向的内存地址;
(2) New 出来的对象都是重新分配内存地址;
(3) 除了 String 类重写了 equals 方法, 其他都与 Object 类的 equals 方法一致;
(4) Integer Double Long Character 等包装库的 equals 方法比较的是值;
----------------
来源: http://www.bubuko.com/infodetail-3211804.html