String字符串的==、equals方法以及对象的==、equals方法的区别
来源:互联网 发布:天涯明月刀ol捏脸数据 编辑:程序博客网 时间:2024/05/16 11:52
前言:我们都知道String也是对象,但是用String的==和equals()来判断和其他对象的==和equals()来判断的结果是不是一样呢?看代码:
package zm.demo;import java.util.HashMap;import java.util.Iterator;import java.util.Map;public class Demo { public static void main(String[] args) { Person p1 = new Person(1, "张三", 20); Person p2 = new Person(1, "张三", 20); System.out.println("比较p1=p2 :" + (p1==p2)); System.out.println("比较p1.equels(p2) :" + (p1.equals(p2))); String s1 = "C博客"; String s2 = "C博客"; System.out.println("比较s1=s2 :" + (s1==s2)); System.out.println("比较s1.equels(s2) :" + (s1.equals(s2))); }}
看结果:
比较p1=p2 :false比较p1.equels(p2) :false比较s1=s2 :true比较s1.equels(s2) :true
明明都是对象,都是比较的==和equals,为什么结果却完全相反呢???
原因:
我们先来说equals()方法:
我们都知道所有的对象基类都是Object,因此我们看Object的源码:
public boolean equals(Object obj) { return (this == obj); }
这就是Object#equals源码,所以,实际上Object的equals方法和==并没有任何区别,就是一样的,因此普通对象的==和equals()都是一样的,比较的是是否为同一对象
而String,它之所以不同,就是因为它重写了equals方法:
看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的equals方法实际上比较的是它的值是否相同。
String的==比较,为什么这里String的==得出得结果也是true呢?
这就涉及到了String的常量池了,String s1 = “C博客”;JVM会首先去常量池中查找是否有”C博客”这个字符串常量,有的话就返回引用地址给s1,没有就将”C博客”字符串常量放入常量池,再返回地址给s1,s2也是”C博客”字符串常量,因此JVM会将常量池中的该字符串引用地址返回给s2,因此实际上s1和s2指向的是同一个字符串字面量,所以才会为true。
再来看这个:
String s3 = new String("C博客");String s4 = new String("C博客");System.out.println("比较s3=s4 :" + (s3==s4));System.out.println("比较s3.equels(s4) :" + (s3.equals(s4)));
得出的结果:
比较s3=s4 :false比较s3.equels(s4) :true
这又是为什么呢?实际上这也涉及到String的内存分布和常量池了:
上面代码在运行期间的内存分配:
- JVM首先会去常量池中查找有没有一个叫“C博客”的字符串常量,如果有,就获取它的引用地址,没有就在常量池(jdk1.7好像常量池也在堆内)中创建一个再返回引用地址;
- 然后遇到了new,就会在堆内存中分配一块内存存储一个叫new String()的对象,该对象里就含有常量池中那个字符串的引用地址;
- 在栈内存中创建一个叫s3的变量,指向堆内存中的刚刚创建的对象;
- 对s4分配内存的时候,也会先去常量池中查找,因为s3已经在常量池中创建了”C博客”的字符串常量,因此就只会返回该字符串的引用地址;
- 在堆中又分配一块内存给一个叫new String()的对象,该对象里也有指向常量池中”C博客”字符串常量的地址;
- 在栈内存中创建一个叫s4的变量,指向堆内存中的刚刚创建的对象。
所以,s3和s4的==比较的时候返回的是false,因为它们指向是不同的对象,而s3.equals(s4)返回true,就是因为String内重写了equals方法了,比较的是对象里的内容,它们都指向常量池中的同一个叫”C博客”的字符串,因此相等。
- String字符串的==、equals方法以及对象的==、equals方法的区别
- Java字符串String:equals方法和==的区别
- String的==和equals()方法的区别
- (java)String 中 ==与equals方法 的区别
- String equals方法和==的区别
- String 的==和equals()方法
- ==和equals方法的区别以及Integer和String的应用
- Java equals 方法以及和 ==的区别
- 字符串==与equals方法的区别
- ==和equals()区别(操作符==与对象equals方法的不同)
- "==" 和 equals方法的区别
- equals()方法与==的区别
- "=="和equals方法的区别
- ==与equals()方法的区别?
- "=="和equals方法的区别
- equals方法和“==”的区别
- equals和"=="方法的区别
- equals()方法和“==”的区别
- 用proteus来做一个R-S触发器
- 第四章
- 构建高可用和弹性伸缩的KV存储系统
- VIJOS-P1512 SuperBrother打鼹鼠
- Maven简介
- String字符串的==、equals方法以及对象的==、equals方法的区别
- 机器视觉中使用光源及偏振镜解决物体反光问题
- Java 23种设计模式之
- U-boot介绍
- 【Android 7.0 Audio 】Andriod Audio Overview
- 数组和指针的区别和联系?
- FP-growth算法——原理
- daughter of Pope Alexander seemed never
- java简单实现一致性哈希算法