== 和 equals
==
==
比较分为两种情况:
- 基本数据类型比较的是两者的值
int a = 10;
double b = 10.0;
long c = 10.0L;
System.out.println(a==b); //true
System.out.println(b==c); //true
基本数据类型存储于内存的栈中,赋值时先在栈中寻找是否有存有该值的地址,若有,则指向该地址,若没有,则开辟空间存放该值再指向。
- 引用数据类型比较的是引用地址是否一致
Object o1 = new Object();
Object o2 = new Object();
System.out.println(o1==o2); //false
System.out.println(o1.equals(o2)); //false
引用数据类型创建时默认继承Object
类,在new
的时候会在堆中开辟空间存储对象,栈中引用通过地址指向堆中的对象,我们实际操作的是栈中的引用。因为o1
和o2
引用指向的地址不同,所以==返回的是false
。
equals
- equals比较的是值
System.out.println(o1.equals(o2)); //false
这里返回false
的原因是Object
类中equals
实现方法采用的是return o1 == o2
。
String str1 = "name";
String str2 = "name";
System.out.println(str1==str2); //true
System.out.println(str1.equals(str2)); //true
String str1="name"
是一种非常特殊的形式,和new
有本质的区别。它是java
中唯一不需要new
就可以产生对象。以String str1="name"
;形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。这种形式的字符串,在JVM
内部发生字符串拘留,即当声明这样的一个字符串后,JVM
会在常量池中先查找有有没有一个值为"name"
的对象,如果有,就会把它赋给当前引用。即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个"name"
,下一次如果有String str1 = "name"
,又会将str1
指向"name"
这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象。
String str1 = new String("name");
String str2 = new String("name");
System.out.println(str1==str2); //false
System.out.println(str1.equals(str2)); //true
通过new
创建的String
会在堆中开辟不同的空间进行存储,栈中的str1
和str2
引用指向不同的内存地址,所以==
会返回false
。str1
和str2
中的值都指向常量池的"name"
,所以equals
返回true
。